$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h" 00002 #include "otsdaq-core/Macros/TablePluginMacros.h" 00003 #include "otsdaq-core/TablePluginDataFormats/DesktopIconTable.h" 00004 #include "otsdaq-core/WebUsersUtilities/WebUsers.h" 00005 00006 #include <stdio.h> 00007 #include <fstream> // std::fstream 00008 #include <iostream> 00009 using namespace ots; 00010 00011 #define DESKTOP_ICONS_FILE \ 00012 std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData/iconList.dat" 00013 00014 // DesktopIconTable Column names 00015 #define COL_NAME "IconName" 00016 #define COL_STATUS TableViewColumnInfo::COL_NAME_STATUS 00017 #define COL_CAPTION "Caption" 00018 #define COL_ALTERNATE_TEXT "AlternateText" 00019 #define COL_FORCE_ONLY_ONE_INSTANCE "ForceOnlyOneInstance" 00020 #define COL_REQUIRED_PERMISSION_LEVEL "RequiredPermissionLevel" 00021 #define COL_IMAGE_URL "ImageURL" 00022 #define COL_WINDOW_CONTENT_URL "WindowContentURL" 00023 #define COL_APP_LINK "LinkToApplicationTable" 00024 #define COL_PARAMETER_LINK "LinkToParameterTable" 00025 #define COL_PARAMETER_KEY "windowParameterKey" 00026 #define COL_PARAMETER_VALUE "windowParameterValue" 00027 #define COL_FOLDER_PATH "FolderPath" 00028 00029 // XDAQ App Column names 00030 #define COL_APP_ID "Id" 00031 00032 //============================================================================== 00033 DesktopIconTable::DesktopIconTable(void) : TableBase("DesktopIconTable") 00034 { 00035 // Icon list no longer passes through file! so delete it from user's $USER_DATA 00036 std::system(("rm -rf " + (std::string)DESKTOP_ICONS_FILE).c_str()); 00037 00039 // WARNING: the names used in C++ MUST match the Table INFO // 00041 00042 // <?xml version="1.0" encoding="UTF-8" standalone="no" ?> 00043 // <ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 00044 // xsi:noNamespaceSchemaLocation="TableInfo.xsd"> <TABLE 00045 // Name="DesktopIconTable"> 00046 // <VIEW Name="DESKTOP_ICON_TABLE" 00047 // Type="File,Database,DatabaseTest" 00048 // 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-%20LinkToApplicationTable%2FApplicationUID%3A%0A%3CINDENT%3EWhen%20the%20Icon%20refers%20to%20an%20otsdaq%20app%2C%20these%20two%20fields%20comprise%20the%20table%20link%20that%20connects%20the%20Icon%20to%20the%20app's%20ID%20-%20the%20app%20ID%20is%20used%20to%20target%20the%20app%20when%20sending%20requests.%20The%20LinkToApplicationTable%20field%20is%20the%20table%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"> 00049 // <COLUMN Type="UID" Name="IconName" StorageName="ICON_NAME" 00050 // DataType="VARCHAR2" DataChoices=""/> <COLUMN Type="OnOff" 00051 // Name="Status" StorageName="STATUS" DataType="VARCHAR2" 00052 // DataChoices=""/> 00053 // <COLUMN Type="Data" Name="Caption" StorageName="CAPTION" 00054 // DataType="VARCHAR2" DataChoices=""/> <COLUMN Type="Data" 00055 // Name="AlternateText" StorageName="ALTERNATE_TEXT" DataType="VARCHAR2" 00056 // DataChoices=""/> 00057 // <COLUMN Type="TrueFalse" Name="ForceOnlyOneInstance" 00058 // StorageName="FORCE_ONLY_ONE_INSTANCE" DataType="VARCHAR2" 00059 // DataChoices=""/> 00060 // <COLUMN Type="Data" Name="RequiredPermissionLevel" 00061 // StorageName="REQUIRED_PERMISSION_LEVEL" DataType="VARCHAR2" 00062 // DataChoices=""/> <COLUMN Type="Data" Name="ImageURL" 00063 // StorageName="IMAGE_URL" DataType="VARCHAR2" DataChoices=""/> 00064 // <COLUMN Type="Data" Name="WindowContentURL" 00065 // StorageName="WINDOW_CONTENT_URL" DataType="VARCHAR2" DataChoices=""/> 00066 // <COLUMN Type="ChildLink-0" Name="LinkToApplicationTable" 00067 // StorageName="LINK_TO_APPLICATION_TABLE" DataType="VARCHAR2" 00068 // DataChoices=""/> 00069 // <COLUMN Type="ChildLinkUID-0" Name="ApplicationUID" 00070 // StorageName="APPLICATION_UID" DataType="VARCHAR2" DataChoices=""/> 00071 // <COLUMN Type="Data" Name="FolderPath" 00072 // StorageName="FOLDER_PATH" DataType="VARCHAR2" DataChoices=""/> 00073 // <COLUMN Type="Comment" Name="CommentDescription" 00074 // StorageName="COMMENT_DESCRIPTION" DataType="VARCHAR2" DataChoices=""/> 00075 // <COLUMN Type="Author" Name="Author" StorageName="AUTHOR" 00076 // DataType="VARCHAR2" DataChoices=""/> 00077 // <COLUMN Type="Timestamp" Name="RecordInsertionTime" 00078 // StorageName="RECORD_INSERTION_TIME" DataType="TIMESTAMP WITH TIMEZONE" 00079 // DataChoices=""/> 00080 // </VIEW> 00081 // </TABLE> 00082 // </ROOT> 00083 } 00084 00085 //============================================================================== 00086 DesktopIconTable::~DesktopIconTable(void) {} 00087 00088 //============================================================================== 00089 void DesktopIconTable::init(ConfigurationManager* configManager) 00090 { 00091 // __COUT__ << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << std::endl; 00092 // __COUT__ << configManager->__SELF_NODE__ << std::endl; 00093 00094 unsigned int intVal; 00095 00096 auto childrenMap = configManager->__SELF_NODE__.getChildren(); 00097 00098 activeDesktopIcons_.clear(); 00099 00100 DesktopIconTable::DesktopIcon* icon; 00101 bool addedAppId; 00102 bool numeric; 00103 unsigned int i; 00104 for(auto& child : childrenMap) 00105 { 00106 if(!child.second.getNode(COL_STATUS).getValue<bool>()) 00107 continue; 00108 00109 activeDesktopIcons_.push_back(DesktopIconTable::DesktopIcon()); 00110 icon = &(activeDesktopIcons_.back()); 00111 00112 icon->caption_ = child.second.getNode(COL_CAPTION).getValue<std::string>(); 00113 icon->alternateText_ = 00114 child.second.getNode(COL_ALTERNATE_TEXT).getValue<std::string>(); 00115 icon->enforceOneWindowInstance_ = 00116 child.second.getNode(COL_FORCE_ONLY_ONE_INSTANCE).getValue<bool>(); 00117 icon->permissionThresholdString_ = 00118 child.second.getNode(COL_REQUIRED_PERMISSION_LEVEL).getValue<std::string>(); 00119 icon->imageURL_ = child.second.getNode(COL_IMAGE_URL).getValue<std::string>(); 00120 icon->windowContentURL_ = 00121 child.second.getNode(COL_WINDOW_CONTENT_URL).getValue<std::string>(); 00122 icon->folderPath_ = child.second.getNode(COL_FOLDER_PATH).getValue<std::string>(); 00123 00124 if(icon->folderPath_ == TableViewColumnInfo::DATATYPE_STRING_DEFAULT) 00125 icon->folderPath_ = ""; // convert DEFAULT to empty string 00126 00127 numeric = true; 00128 for(i = 0; i < icon->permissionThresholdString_.size(); ++i) 00129 if(!(icon->permissionThresholdString_[i] >= '0' && 00130 icon->permissionThresholdString_[i] <= '9')) 00131 { 00132 numeric = false; 00133 break; 00134 } 00135 // for backwards compatibility, if permissions threshold is a single number 00136 // assume it is the threshold intended for the WebUsers::DEFAULT_USER_GROUP group 00137 if(numeric) 00138 icon->permissionThresholdString_ = 00139 WebUsers::DEFAULT_USER_GROUP + ":" + icon->permissionThresholdString_; 00140 00141 // remove all commas from member strings because desktop icons are served to 00142 // client in comma-separated string 00143 icon->caption_ = removeCommas( 00144 icon->caption_, false /*andHexReplace*/, true /*andHTMLReplace*/); 00145 icon->alternateText_ = removeCommas( 00146 icon->alternateText_, false /*andHexReplace*/, true /*andHTMLReplace*/); 00147 icon->imageURL_ = removeCommas(icon->imageURL_, true /*andHexReplace*/); 00148 icon->windowContentURL_ = 00149 removeCommas(icon->windowContentURL_, true /*andHexReplace*/); 00150 icon->folderPath_ = removeCommas( 00151 icon->folderPath_, false /*andHexReplace*/, true /*andHTMLReplace*/); 00152 00153 // add URN/LID to windowContentURL_, if link is given 00154 addedAppId = false; 00155 if(!child.second.getNode(COL_APP_LINK).isDisconnected()) 00156 { 00157 // if last character is not '=' 00158 // then assume need to add "?urn=" 00159 if(icon->windowContentURL_[icon->windowContentURL_.size() - 1] != '=') 00160 icon->windowContentURL_ += "?urn="; 00161 00162 //__COUT__ << "Following Application link." << std::endl; 00163 child.second.getNode(COL_APP_LINK).getNode(COL_APP_ID).getValue(intVal); 00164 icon->windowContentURL_ += std::to_string(intVal); 00165 00166 //__COUT__ << "URN/LID=" << intVal << std::endl; 00167 addedAppId = true; 00168 } 00169 00170 // add parameters if link is given 00171 if(!child.second.getNode(COL_PARAMETER_LINK).isDisconnected()) 00172 { 00173 // if there is no '?' found 00174 // then assume need to add "?" 00175 if(icon->windowContentURL_.find('?') == std::string::npos) 00176 icon->windowContentURL_ += '?'; 00177 else if(addedAppId || 00178 icon->windowContentURL_[icon->windowContentURL_.size() - 1] != 00179 '?') // if not first parameter, add & 00180 icon->windowContentURL_ += '&'; 00181 00182 // now add each paramter separated by & 00183 auto paramGroupMap = child.second.getNode(COL_PARAMETER_LINK).getChildren(); 00184 bool notFirst = false; 00185 for(const auto param : paramGroupMap) 00186 { 00187 if(notFirst) 00188 icon->windowContentURL_ += '&'; 00189 else 00190 notFirst = true; 00191 icon->windowContentURL_ += 00192 ConfigurationManager::encodeURIComponent( 00193 param.second.getNode(COL_PARAMETER_KEY).getValue<std::string>()) + 00194 "=" + 00195 ConfigurationManager::encodeURIComponent( 00196 param.second.getNode(COL_PARAMETER_VALUE) 00197 .getValue<std::string>()); 00198 } 00199 } 00200 } // end main icon extraction loop 00201 00202 // 00203 // //generate icons file 00204 // std::fstream fs; 00205 // fs.open(DESKTOP_ICONS_FILE, std::fstream::out | std::fstream::trunc); 00206 // if(fs.fail()) 00207 // { 00208 // __SS__ << "Failed to open Desktop Icons run file: " << DESKTOP_ICONS_FILE << 00209 // std::endl; 00210 // __SS_THROW__; 00211 // } 00212 // 00213 // for(auto &child:childrenMap) 00214 // { 00215 // child.second.getNode(COL_STATUS ).getValue(status); 00216 // if(!status) continue; 00217 // 00218 // if(first) first = false; 00219 // else fs << ","; 00220 // 00221 // child.second.getNode(COL_CAPTION ).getValue(val); 00222 // fs << removeCommas(val, false, true); 00223 // //__COUT__ << "Icon caption: " << val << std::endl; 00224 // 00225 // fs << ","; 00226 // child.second.getNode(COL_ALTERNATE_TEXT ).getValue(val); 00227 // fs << removeCommas(val, false, true); 00228 // 00229 // fs << ","; 00230 // child.second.getNode(COL_FORCE_ONLY_ONE_INSTANCE ).getValue(status); 00231 // fs << (status?"1":"0"); 00232 // 00233 // fs << ","; 00234 // child.second.getNode(COL_REQUIRED_PERMISSION_LEVEL ).getValue(val); 00235 // fs << removeCommas(val); 00236 // 00237 // fs << ","; 00238 // child.second.getNode(COL_IMAGE_URL ).getValue(val); 00239 // fs << removeCommas(val,true); 00240 // 00241 // fs << ","; 00242 // child.second.getNode(COL_WINDOW_CONTENT_URL ).getValue(val); 00243 // val = removeCommas(val,true); 00244 // fs << val; 00245 // 00246 // bool addedAppId = false; 00247 // //add URN/LID if link is given 00248 // if(!child.second.getNode(COL_APP_LINK ).isDisconnected()) 00249 // { 00250 // //if last character is not '=' 00251 // // then assume need to add "?urn=" 00252 // if(val[val.size()-1] != '=') 00253 // fs << "?urn="; 00254 // 00255 // //__COUT__ << "Following Application link." << std::endl; 00256 // child.second.getNode(COL_APP_LINK ).getNode(COL_APP_ID 00257 //).getValue(intVal); 00258 // 00259 // //__COUT__ << "URN/LID=" << intVal << std::endl; 00260 // fs << intVal; //append number 00261 // addedAppId = true; 00262 // } 00263 // 00264 // //add parameters if link is given 00265 // if(!child.second.getNode(COL_PARAMETER_LINK ).isDisconnected()) 00266 // { 00267 // //if there is no '?' found 00268 // // then assume need to add "?" 00269 // if(val.find('?') == std::string::npos) 00270 // fs << '?'; 00271 // else if(addedAppId || 00272 // val[val.size()-1] != '?') //if not first parameter, add & 00273 // fs << '&'; 00274 // 00275 // //now add each paramter separated by & 00276 // auto paramGroupMap = child.second.getNode(COL_PARAMETER_LINK 00277 //).getChildren(); bool notFirst = false; for(const auto 00278 // param:paramGroupMap) 00279 // { 00280 // if(notFirst) 00281 // fs << '&'; 00282 // else 00283 // notFirst = true; 00284 // fs << ConfigurationManager::encodeURIComponent( 00285 // param.second.getNode(COL_PARAMETER_KEY).getValue<std::string>()) 00286 //<< 00287 //"=" 00288 //<< ConfigurationManager::encodeURIComponent( 00289 // param.second.getNode(COL_PARAMETER_VALUE).getValue<std::string>()); 00290 // } 00291 // } 00292 // 00293 // fs << ","; 00294 // child.second.getNode(COL_FOLDER_PATH ).getValue(val); 00295 // if(val == TableViewColumnInfo::DATATYPE_STRING_DEFAULT) val = ""; 00296 // fs << removeCommas(val,true); 00297 // } 00298 // 00299 // //close icons file 00300 // fs.close(); 00301 } 00302 00303 std::string DesktopIconTable::removeCommas(const std::string& str, 00304 bool andHexReplace, 00305 bool andHTMLReplace) 00306 { 00307 std::string retStr = ""; 00308 retStr.reserve(str.length()); 00309 00310 for(unsigned int i = 0; i < str.length(); ++i) 00311 if(str[i] != ',') 00312 retStr += str[i]; 00313 else if(andHexReplace) 00314 retStr += "%2C"; 00315 else if(andHTMLReplace) 00316 retStr += ","; 00317 00318 return retStr; 00319 } 00320 00321 DEFINE_OTS_TABLE(DesktopIconTable)