00001 #include "otsdaq-core/ConfigurationPluginDataFormats/DesktopIconConfiguration.h" 00002 #include "otsdaq-core/Macros/ConfigurationPluginMacros.h" 00003 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h" 00004 00005 #include <iostream> 00006 #include <fstream> // std::fstream 00007 #include <stdio.h> 00008 using namespace ots; 00009 00010 #define DESKTOP_ICONS_FILE std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData/iconList.dat" 00011 00012 //DesktopIconConfiguration Column names 00013 #define COL_NAME "IconName" 00014 #define COL_STATUS ViewColumnInfo::COL_NAME_STATUS 00015 #define COL_CAPTION "Caption" 00016 #define COL_ALTERNATE_TEXT "AlternateText" 00017 #define COL_FORCE_ONLY_ONE_INSTANCE "ForceOnlyOneInstance" 00018 #define COL_REQUIRED_PERMISSION_LEVEL "RequiredPermissionLevel" 00019 #define COL_IMAGE_URL "ImageURL" 00020 #define COL_WINDOW_CONTENT_URL "WindowContentURL" 00021 #define COL_APP_LINK "LinkToApplicationConfiguration" 00022 #define COL_PARAMETER_LINK "LinkToParameterConfiguration" 00023 #define COL_PARAMETER_KEY "windowParameterKey" 00024 #define COL_PARAMETER_VALUE "windowParameterValue" 00025 #define COL_FOLDER_PATH "FolderPath" 00026 00027 //XDAQ App Column names 00028 #define COL_APP_ID "Id" 00029 00030 00031 00032 //============================================================================== 00033 DesktopIconConfiguration::DesktopIconConfiguration(void) : 00034 ConfigurationBase("DesktopIconConfiguration") 00035 { 00037 //WARNING: the names used in C++ MUST match the Configuration INFO // 00039 00040 // <?xml version="1.0" encoding="UTF-8" standalone="no" ?> 00041 // <ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ConfigurationInfo.xsd"> 00042 // <CONFIGURATION Name="DesktopIconConfiguration"> 00043 // <VIEW Name="DESKTOP_ICON_CONFIGURATION" Type="File,Database,DatabaseTest" Description="This%20table%20is%20used%20to%20specify%20the%20Icons%20available%20on%20the%20otsdaq%20Desktop.%20%0A%0AUsually%20a%20Desktop%20Icon%20opens%20the%20GUI%20to%20an%20otsdaq%20app%2C%20but%20an%20Icon%20may%20be%20configured%20to%20open%20any%20content%20accessible%20through%20the%20user's%20browser%20(Note%3A%20the%20target%20server%20may%20have%20to%20allow%20cross-origin%20requests%20for%20full%20functionality).%20%0A%0AHere%20is%20an%20explanation%20of%20the%20features%20associated%20with%20each%20column%3A%0A%3CINDENT%3E%0A-%20IconName%3A%0A%3CINDENT%3EThis%20is%20the%20unique%20ID%20value%20for%20each%20row.%3C%2FINDENT%3E%0A-%20Status%3A%0A%3CINDENT%3EIf%20On%2C%20the%20Icon%20will%20be%20shown%20on%20the%20Desktop.%20When%20Off%2C%20the%20Icon%20will%20not%20be%20displayed.%3C%2FINDENT%3E%0A-%20Caption%3A%0A%3CINDENT%3EThis%20is%20the%20text%20shown%20underneath%20the%20Icon.%3C%2FINDENT%3E%0A-%20AlternateText%3A%0A%3CINDENT%3EIf%20the%20ImageURL%20is%20omitted%20(left%20as%20default%20or%20blank)%2C%20then%20the%20alternate%20text%20is%20used%20in%20place%20of%20the%20Icon%20image.%20This%20is%20useful%20if%20you%20have%20not%20yet%20found%20an%20image%20to%20use%20for%20a%20particular%20icon.%3C%2FINDENT%3E%0A-%20ForceOnlyOneInstance%3A%0A%3CINDENT%3EIf%20True%2C%20then%20only%20window%20is%20allowed%20on%20the%20Desktop.%20If%20False%2C%20then%20each%20time%20the%20Icon%20is%20clicked%20a%20new%20instance%20of%20the%20window%20will%20open.%20For%20example%2C%20it%20is%20common%20to%20force%20only%20one%20instance%20of%20the%20state%20machine%20window.%3C%2FINDENT%3E%0A-%20RequiredPermissionLevel%3A%0A%3CINDENT%3EThis%20value%20is%20the%20minimum%20permission%20level%20for%20a%20user%20to%20have%20access%20to%20this%20Icon.%20If%20a%20user%20has%20insufficient%20access%2C%20the%20Icon%20will%20not%20appear%20on%20their%20Desktop.%20As%20a%20reminder%2C%20permission%20levels%20go%20from%201%20(lowest)%20to%20255%20(admin-level)%3B%20and%20only%20admins%20can%20modify%20the%20access%20level%20of%20users.%3C%2FINDENT%3E%0A-%20ImageURL%3A%0A%3CINDENT%3EThis%20is%20the%20URL%20to%20the%20image%20used%20for%20the%20Icon.%20The%20native%20resolution%20for%20Icons%20is%2064%20x%2064%20pixels.%20If%20left%20as%20the%20default%20value%20or%20blank%2C%20the%20the%20AlternateText%20field%20will%20be%20used%20for%20the%20Icon%20image.%3C%2FINDENT%3E%0A-%20WindowContentURL%3A%0A%3CINDENT%3EThis%20is%20the%20URL%20of%20the%20window%20content%20that%20will%20be%20opened%20when%20the%20user%20clicks%20this%20Icon.%20The%20window%20content%20is%20usually%20an%20otsdaq%20app%20but%20may%20be%20any%20web%20content%20accessible%20through%20the%20user's%20browser.%3C%2FINDENT%3E%0A-%20LinkToApplicationConfiguration%2FApplicationUID%3A%0A%3CINDENT%3EWhen%20the%20Icon%20refers%20to%20an%20otsdaq%20app%2C%20these%20two%20fields%20comprise%20the%20configuration%20link%20that%20connects%20the%20Icon%20to%20the%20app's%20ID%20-%20the%20app%20ID%20is%20used%20to%20target%20the%20app%20when%20sending%20requests.%20The%20LinkToApplicationConfiguration%20field%20is%20the%20configuration%20table%20part%20of%20the%20link%20and%20the%20ApplicationUID%20field%20is%20the%20UID%20part%20of%20the%20link.%3C%2FINDENT%3E%0A-%20FolderPath%3A%0A%3CINDENT%3EThis%20field%20is%20used%20to%20organize%20Icons%20into%20folders%20on%20the%20Desktop.%20For%20example%2C%20a%20value%20of%20%22myFolder%2FmySubfolder%22%20places%20this%20Icon%20inside%20a%20folder%20named%20%22mySubFolder%22%20which%20is%20inside%20the%20folder%20%22myFolder%22%20on%20the%20Desktop.%3C%2FINDENT%3E%0A%3C%2FINDENT%3E"> 00044 // <COLUMN Type="UID" Name="IconName" StorageName="ICON_NAME" DataType="VARCHAR2" DataChoices=""/> 00045 // <COLUMN Type="OnOff" Name="Status" StorageName="STATUS" DataType="VARCHAR2" DataChoices=""/> 00046 // <COLUMN Type="Data" Name="Caption" StorageName="CAPTION" DataType="VARCHAR2" DataChoices=""/> 00047 // <COLUMN Type="Data" Name="AlternateText" StorageName="ALTERNATE_TEXT" DataType="VARCHAR2" DataChoices=""/> 00048 // <COLUMN Type="TrueFalse" Name="ForceOnlyOneInstance" StorageName="FORCE_ONLY_ONE_INSTANCE" DataType="VARCHAR2" DataChoices=""/> 00049 // <COLUMN Type="Data" Name="RequiredPermissionLevel" StorageName="REQUIRED_PERMISSION_LEVEL" DataType="VARCHAR2" DataChoices=""/> 00050 // <COLUMN Type="Data" Name="ImageURL" StorageName="IMAGE_URL" DataType="VARCHAR2" DataChoices=""/> 00051 // <COLUMN Type="Data" Name="WindowContentURL" StorageName="WINDOW_CONTENT_URL" DataType="VARCHAR2" DataChoices=""/> 00052 // <COLUMN Type="ChildLink-0" Name="LinkToApplicationConfiguration" StorageName="LINK_TO_APPLICATION_CONFIGURATION" DataType="VARCHAR2" DataChoices=""/> 00053 // <COLUMN Type="ChildLinkUID-0" Name="ApplicationUID" StorageName="APPLICATION_UID" DataType="VARCHAR2" DataChoices=""/> 00054 // <COLUMN Type="Data" Name="FolderPath" StorageName="FOLDER_PATH" DataType="VARCHAR2" DataChoices=""/> 00055 // <COLUMN Type="Comment" Name="CommentDescription" StorageName="COMMENT_DESCRIPTION" DataType="VARCHAR2" DataChoices=""/> 00056 // <COLUMN Type="Author" Name="Author" StorageName="AUTHOR" DataType="VARCHAR2" DataChoices=""/> 00057 // <COLUMN Type="Timestamp" Name="RecordInsertionTime" StorageName="RECORD_INSERTION_TIME" DataType="TIMESTAMP WITH TIMEZONE" DataChoices=""/> 00058 // </VIEW> 00059 // </CONFIGURATION> 00060 // </ROOT> 00061 00062 } 00063 00064 //============================================================================== 00065 DesktopIconConfiguration::~DesktopIconConfiguration(void) 00066 {} 00067 00068 //============================================================================== 00069 void DesktopIconConfiguration::init(ConfigurationManager *configManager) 00070 { 00071 __COUT__ << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << std::endl; 00072 __COUT__ << configManager->__SELF_NODE__ << std::endl; 00073 00074 00075 bool status; 00076 std::string val; 00077 unsigned int intVal; 00078 00079 bool first = true; 00080 00081 auto childrenMap = configManager->__SELF_NODE__.getChildren(); 00082 00083 00084 //generate icons file 00085 std::fstream fs; 00086 fs.open(DESKTOP_ICONS_FILE, std::fstream::out | std::fstream::trunc); 00087 if(fs.fail()) 00088 { 00089 __SS__ << "Failed to open Desktop Icons run file: " << DESKTOP_ICONS_FILE << std::endl; 00090 throw std::runtime_error(ss.str()); 00091 } 00092 00093 for(auto &child:childrenMap) 00094 { 00095 child.second.getNode(COL_STATUS ).getValue(status); 00096 if(!status) continue; 00097 00098 if(first) first = false; 00099 else fs << ","; 00100 00101 child.second.getNode(COL_CAPTION ).getValue(val); 00102 fs << removeCommas(val, false, true); 00103 //__COUT__ << "Icon caption: " << val << std::endl; 00104 00105 fs << ","; 00106 child.second.getNode(COL_ALTERNATE_TEXT ).getValue(val); 00107 fs << removeCommas(val, false, true); 00108 00109 fs << ","; 00110 child.second.getNode(COL_FORCE_ONLY_ONE_INSTANCE ).getValue(status); 00111 fs << (status?"1":"0"); 00112 00113 fs << ","; 00114 child.second.getNode(COL_REQUIRED_PERMISSION_LEVEL ).getValue(val); 00115 fs << removeCommas(val); 00116 00117 fs << ","; 00118 child.second.getNode(COL_IMAGE_URL ).getValue(val); 00119 fs << removeCommas(val,true); 00120 00121 fs << ","; 00122 child.second.getNode(COL_WINDOW_CONTENT_URL ).getValue(val); 00123 val = removeCommas(val,true); 00124 fs << val; 00125 00126 bool addedAppId = false; 00127 //add URN/LID if link is given 00128 if(!child.second.getNode(COL_APP_LINK ).isDisconnected()) 00129 { 00130 //if last character is not '=' 00131 // then assume need to add "?urn=" 00132 if(val[val.size()-1] != '=') 00133 fs << "?urn="; 00134 00135 //__COUT__ << "Following Application link." << std::endl; 00136 child.second.getNode(COL_APP_LINK ).getNode(COL_APP_ID ).getValue(intVal); 00137 00138 //__COUT__ << "URN/LID=" << intVal << std::endl; 00139 fs << intVal; //append number 00140 addedAppId = true; 00141 } 00142 00143 //add parameters if link is given 00144 if(!child.second.getNode(COL_PARAMETER_LINK ).isDisconnected()) 00145 { 00146 //if there is no '?' found 00147 // then assume need to add "?" 00148 if(val.find('?') == std::string::npos) 00149 fs << '?'; 00150 else if(addedAppId || 00151 val[val.size()-1] != '?') //if not first parameter, add & 00152 fs << '&'; 00153 00154 //now add each paramter separated by & 00155 auto paramGroupMap = child.second.getNode(COL_PARAMETER_LINK ).getChildren(); 00156 bool notFirst = false; 00157 for(const auto param:paramGroupMap) 00158 { 00159 if(notFirst) 00160 fs << '&'; 00161 else 00162 notFirst = true; 00163 fs << ConfigurationManager::encodeURIComponent( 00164 param.second.getNode(COL_PARAMETER_KEY).getValue<std::string>()) << "=" << 00165 ConfigurationManager::encodeURIComponent( 00166 param.second.getNode(COL_PARAMETER_VALUE).getValue<std::string>()); 00167 } 00168 } 00169 00170 fs << ","; 00171 child.second.getNode(COL_FOLDER_PATH ).getValue(val); 00172 if(val == ViewColumnInfo::DATATYPE_STRING_DEFAULT) val = ""; 00173 fs << removeCommas(val,true); 00174 } 00175 00176 //close icons file 00177 fs.close(); 00178 } 00179 00180 std::string DesktopIconConfiguration::removeCommas(const std::string &str, 00181 bool andHexReplace, bool andHTMLReplace) 00182 { 00183 std::string retStr = ""; 00184 retStr.reserve(str.length()); 00185 00186 for(unsigned int i=0;i<str.length();++i) 00187 if(str[i] != ',') 00188 retStr += str[i]; 00189 else if(andHexReplace) 00190 retStr += "%2C"; 00191 else if(andHTMLReplace) 00192 retStr += ","; 00193 00194 return retStr; 00195 } 00196 00197 DEFINE_OTS_CONFIGURATION(DesktopIconConfiguration)