Skip to content

Commit 1bded7c

Browse files
Repository refactoring & cleanup, gathering XML classes into the one project
1 parent 3db7a55 commit 1bded7c

File tree

9 files changed

+368
-343
lines changed

9 files changed

+368
-343
lines changed

DEVELOPMENT.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,19 @@ Contributing
77
* Feel free to create a discussion or a new issue for every new contribution.
88

99
## Building tips
10-
0. Ensure that you have NodeJS (npm as well) installed, and executed the following:
11-
1. `npm install` (to install all required dependencies).
10+
0. Ensure that you have NodeJS (npm as well) installed, and executed the following in the project directory:
11+
1. `npm install` to install all required dependencies;
12+
2. `npm install -g gulp` to install gulp builder globally (may be optional if you know how to trigger gulp without global binding);
1213
1. Having changes made, export the project:
1314
1. Run `gulp` command to build the project;
1415
3. Find `build/CacheWebTerminal-v*.xml` file and import it to the studio.
15-
2. By making changes in studio files (*.cls, *.mac) just export the code into appropriate files in repository. (insert changes by copying them into `export/template.xml` file)
16+
2. By making changes in studio files (*.cls) just export the code into `export` repository directory.
17+
1. NOTE: Some files as `WebTerminal/StaticContent.xml` contain special tags like `{{replace:*}}`, so that files cannot be directly imported from studio without modifying. Please, check file differences to ensure that you haven't rewritten any of those;
18+
2. NOTE: When creating or changing classes, put their XML files into `export/WebTerminal` directory or any sub-directory which will be built as sub-packages.
1619

1720
## Applications Integration
1821
If you want to integrate WebTerminal with your application, follow the next tips & tricks:
19-
* A `NS` parameter of GET request can set default namespace. For example, URL `../terminal/?NS=USER` will open terminal in USER namespace.
20-
* In order to use IFrame to insert terminal on page, you may need to add `sandbox="allow-same-origin allow-scripts"` attribute to IFrame tag to enable storage and scripts which are required.
21-
* To get latest version of terminal, you can parse [latestVersion](http://intersystems-ru.github.io/webterminal/latestVersion) file which is always available on WEB and then request XML to import from `http://intersystems-ru.github.io/webterminal/files/WebTerminal-<b>{FILE PART}</b>.xml`.
22+
* A `NS` parameter of GET request can set default namespace. For example, URL `../terminal/?NS=USER` will open terminal in USER namespace;
23+
* In order to use IFrame to insert terminal on page, you may need to add `sandbox="allow-same-origin allow-scripts"` attribute to IFrame tag to enable storage and scripts which are required;
24+
* To get latest version of terminal, you can parse [latestVersion](http://intersystems-ru.github.io/webterminal/latestVersion) file which is always available on WEB and then request XML to import from `http://intersystems-ru.github.io/webterminal/files/WebTerminal-<b>{FILE PART}</b>.xml`;
2225
* Web Terminal is able to auto-update itself, just execute `/update` command in the terminal.

export/template.xml renamed to export/WebTerminal/Engine.xml

Lines changed: 2 additions & 311 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<Export generator="Cache" version="25">
2+
<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2015.3 (Build 215U)" ts="2015-12-15 14:54:57">
33
<Class name="WebTerminal.Engine">
44
<Description>
55
Cache WEB Terminal version X.X.X/*build.replace:pkg.version*/ core.
66
This class is the server-side core of the terminal application.</Description>
77
<Super>%CSP.WebSocket,%Library.Routine</Super>
8+
<TimeChanged>63899,77962</TimeChanged>
89
<TimeCreated>63891,56786.028532</TimeCreated>
910

1011
<UDLText name="T">
@@ -1125,314 +1126,4 @@ New connection established: require auth key, login and start client loop.</Desc
11251126
]]></Implementation>
11261127
</Method>
11271128
</Class>
1128-
1129-
1130-
<Class name="WebTerminal.Installer">
1131-
<Description>
1132-
Importing this class will install Cache WEB Terminal properly.</Description>
1133-
<CompileAfter>Engine,Router,StaticContent</CompileAfter>
1134-
<Super>%Projection.AbstractProjection</Super>
1135-
<TimeChanged>63898,2021.685611</TimeChanged>
1136-
<TimeCreated>63890,71053.144208</TimeCreated>
1137-
1138-
<Parameter name="DispatchClass">
1139-
<Default>WebTerminal.Router</Default>
1140-
</Parameter>
1141-
1142-
<Projection name="Reference">
1143-
<Type>Installer</Type>
1144-
</Projection>
1145-
1146-
<Method name="CreateProjection">
1147-
<Description>
1148-
This method is invoked when a class is compiled.</Description>
1149-
<ClassMethod>1</ClassMethod>
1150-
<FormalSpec><![CDATA[cls:%String,&params]]></FormalSpec>
1151-
<ReturnType>%Status</ReturnType>
1152-
<Implementation><![CDATA[
1153-
set ns = $NAMESPACE
1154-
zn:ns'="%SYS" "%SYS"
1155-
do ##class(Security.System).GetInstallationSecuritySetting(.security)
1156-
set cspProperties("AutheEnabled") = 32 // password by default, 64 for no password
1157-
set cspProperties("NameSpace") = ns // terminal works only in %SYS namespace, only in % package
1158-
set cspProperties("Description") = "A WEB application for Cache WEB Terminal."
1159-
set cspProperties("IsNameSpaceDefault") = 0
1160-
set cspProperties("DispatchClass") = ..#DispatchClass
1161-
if ('##class(Security.Applications).Exists("/terminal")) {
1162-
w !, "Creating WEB application ""/terminal""..."
1163-
set tSC = ##class(Security.Applications).Create("/terminal", .cspProperties)
1164-
if $$$ISERR(tSC) throw ##class(%Installer.Exception).CreateFromStatus(tSC)
1165-
w !, "WEB application ""/terminal"" is created."
1166-
//set ^SYS("Security", "CSP", "AllowClass", "/terminal/", ..#DispatchClass) = 1
1167-
} else {
1168-
do ##class(Security.Applications).Get("/terminal", .props)
1169-
if (props("DispatchClass") '= ..#DispatchClass) {
1170-
w !, "WARNING! WEB application ""/terminal"" exists but does not refer to ",
1171-
DispatchClass, ".", !, "Please, set correct dispatch class for this application ",
1172-
"or create a terminal WEB-application manually."
1173-
} else {
1174-
w !, "WEB application ""/terminal"" already exists, so it is ready to use."
1175-
}
1176-
}
1177-
set status = ##Class(Config.Namespaces).Get("%All")
1178-
if ($$$ISERR(status)) { // no namespace %All
1179-
w !, "Creating %All namespace..."
1180-
set Properties("Globals") = "CACHETEMP"
1181-
set Properties("Library") = "CACHELIB"
1182-
set Properties("Routines") = "CACHETEMP"
1183-
set Properties("SysGlobals") = "CACHESYS"
1184-
set Properties("SysRoutines") = "CACHESYS"
1185-
set Properties("TempGlobals") = "CACHETEMP"
1186-
set status = ##Class(Config.Namespaces).Create("%All", .Properties)
1187-
if ($$$ISERR(status)) {
1188-
do $System.Status.DisplayError(status)
1189-
quit status
1190-
} else {
1191-
w !, "%All namespace is created."
1192-
}
1193-
}
1194-
w !, "Mapping %WebTerminal package into all namespaces:"
1195-
set mapTo = $LISTBUILD("%All", "SAMPLES", "DOCBOOK")
1196-
do ##Class(Config.Namespaces).Get("USER", .InstallNSProps)
1197-
set Properties("Database") = $get(InstallNSProps("Routines"))
1198-
set ptr = 0
1199-
while $LISTNEXT(mapTo, ptr, value) {
1200-
continue:(ns = value)
1201-
w " ", value
1202-
set status = ##Class(Config.MapPackages).Create(value, "WebTerminal", .Properties)
1203-
if ($$$ISERR(status)) {
1204-
do $SYSTEM.Status.DisplayError(status)
1205-
}
1206-
}
1207-
w ".", !, "Mapping complete."
1208-
w !, "WebTerminal package successfully mapped into all namespaces."
1209-
zn:ns'="%SYS" ns
1210-
quit $$$OK
1211-
]]></Implementation>
1212-
</Method>
1213-
1214-
<Method name="RemoveProjection">
1215-
<Description>
1216-
This method is invoked when a class is 'uncompiled'.</Description>
1217-
<ClassMethod>1</ClassMethod>
1218-
<FormalSpec><![CDATA[cls:%String,&params,recompile:%Boolean]]></FormalSpec>
1219-
<ReturnType>%Status</ReturnType>
1220-
<Implementation><![CDATA[
1221-
set ns = $NAMESPACE
1222-
zn:ns'="%SYS" "%SYS"
1223-
if (##class(Security.Applications).Exists("/terminal")) {
1224-
do ##class(Security.Applications).Get("/terminal", .props)
1225-
if (props("DispatchClass") '= ..#DispatchClass) {
1226-
w !, "Won't remove WEB-application ""/terminal"" because it does not refer to ",
1227-
"dispatch class anymore."
1228-
} else {
1229-
w !, "Deleting WEB application ""/terminal""..."
1230-
do ##class(Security.Applications).Delete("/terminal")
1231-
kill ^SYS("Security", "CSP", "AllowClass", "/terminal/", ..#DispatchClass)
1232-
w !, "WEB application ""/terminal"" was successfully removed."
1233-
}
1234-
}
1235-
w !, "Unmapping %WebTerminal package from all namespaces:"
1236-
set mapTo = $LISTBUILD("%All", "SAMPLES", "DOCBOOK")
1237-
set ptr = 0
1238-
while $LISTNEXT(mapTo, ptr, value) {
1239-
continue:(ns = value)
1240-
w " ", value
1241-
set status = ##Class(Config.MapPackages).Delete(value, "WebTerminal")
1242-
if ($$$ISERR(status)) {
1243-
do $SYSTEM.Status.DisplayError(status)
1244-
}
1245-
}
1246-
w ".", !, "Unmapping complete."
1247-
kill ^%WebTerminal.Autocomplete
1248-
zn:ns'="%SYS" ns
1249-
QUIT $$$OK
1250-
]]></Implementation>
1251-
</Method>
1252-
</Class>
1253-
1254-
1255-
<Class name="WebTerminal.Router">
1256-
<Description>
1257-
The REST interface: class that routes HTTP requests</Description>
1258-
<CompileAfter>StaticContent</CompileAfter>
1259-
<Super>%CSP.REST</Super>
1260-
<TimeCreated>63890,69646.001045</TimeCreated>
1261-
1262-
<XData name="UrlMap">
1263-
<Data><![CDATA[
1264-
<Routes>
1265-
<Route Url="/" Method="GET" Call="Index"/>
1266-
<Route Url="/index" Method="GET" Call="Index"/>
1267-
<Route Url="/css/terminal.css" Method="GET" Call="GetCss"/>
1268-
<Route Url="/css/terminal-theme/:theme" Method="GET" Call="GetTheme"/>
1269-
<Route Url="/js/terminal.js" Method="GET" Call="GetJs"/>
1270-
<Route Url="/autocomplete" Method="GET" Call="WriteAutocomplete"/>
1271-
</Routes>
1272-
]]></Data>
1273-
</XData>
1274-
1275-
<Method name="WriteAutocomplete">
1276-
<Description>
1277-
Method returns autocomplete data in JSON format</Description>
1278-
<ClassMethod>1</ClassMethod>
1279-
<ReturnType>%Status</ReturnType>
1280-
<Implementation><![CDATA[
1281-
set namespace = %request.Get("NS", $znspace)
1282-
set %response.CharSet = "utf-8"
1283-
set %response.ContentType = "application/json"
1284-
write $get(^%WebTerminal.Autocomplete(namespace), "{}")
1285-
return $$$OK
1286-
]]></Implementation>
1287-
</Method>
1288-
1289-
<Method name="WriteStatic">
1290-
<Description>
1291-
Calls StaticContent.Write method or sends not modified header. Type have to be "css" or "js"</Description>
1292-
<ClassMethod>1</ClassMethod>
1293-
<FormalSpec>type:%String,Auth:%String="",ContentType:%String=""</FormalSpec>
1294-
<Private>1</Private>
1295-
<Implementation><![CDATA[
1296-
#define CompileTime ##Expression("""" _ $zd($h, 11) _ ", "_ $zdt($NOW(0), 2,1) _ " GMT""")
1297-
set %response.CharSet = "utf-8"
1298-
set %response.ContentType = $case(type,
1299-
"css": "text/css",
1300-
"js": "text/javascript",
1301-
"html": "text/html",
1302-
: $case(ContentType="", 1:"text/plain", :ContentType)
1303-
)
1304-
do %response.SetHeader("Last-Modified", $$$CompileTime)
1305-
1306-
if (%request.GetCgiEnv("HTTP_IF_MODIFIED_SINCE")=$$$CompileTime) && (Auth = "") {
1307-
set %response.Status = "304 Not Modified"
1308-
} else {
1309-
do ##class(StaticContent).Write(type, Auth)
1310-
}
1311-
]]></Implementation>
1312-
</Method>
1313-
1314-
<Method name="GetCss">
1315-
<Description>
1316-
Method writes application CSS.</Description>
1317-
<ClassMethod>1</ClassMethod>
1318-
<ReturnType>%Status</ReturnType>
1319-
<Implementation><![CDATA[
1320-
do ..WriteStatic("css")
1321-
return $$$OK
1322-
]]></Implementation>
1323-
</Method>
1324-
1325-
<Method name="GetTheme">
1326-
<Description>
1327-
Method writes application theme.</Description>
1328-
<ClassMethod>1</ClassMethod>
1329-
<FormalSpec>Theme:%String</FormalSpec>
1330-
<ReturnType>%Status</ReturnType>
1331-
<Implementation><![CDATA[
1332-
do ..WriteStatic("Theme"_$REPLACE(Theme, ".css", ""),,"text/css")
1333-
return $$$OK
1334-
]]></Implementation>
1335-
</Method>
1336-
1337-
<Method name="GetJs">
1338-
<Description>
1339-
Method writes application JavaScript.</Description>
1340-
<ClassMethod>1</ClassMethod>
1341-
<ReturnType>%Status</ReturnType>
1342-
<Implementation><![CDATA[
1343-
do ..WriteStatic("js")
1344-
return $$$OK
1345-
]]></Implementation>
1346-
</Method>
1347-
1348-
<Method name="Index">
1349-
<Description>
1350-
Method writes application HTML.</Description>
1351-
<ClassMethod>1</ClassMethod>
1352-
<ReturnType>%Status</ReturnType>
1353-
<Implementation><![CDATA[
1354-
set cookie = %session.CSPSessionCookie
1355-
// Put the name of authorized user in a global to authorize WebSocket WebTerminal connection
1356-
set ^%WebTerminal.AuthUser(cookie) = $LB(
1357-
$LISTGET(%session.SecurityContext, 1), // username
1358-
$horolog // granting ticket date
1359-
)
1360-
do ..WriteStatic("html", cookie)
1361-
return $$$OK
1362-
]]></Implementation>
1363-
</Method>
1364-
</Class>
1365-
1366-
1367-
<Class name="WebTerminal.StaticContent">
1368-
<Description>
1369-
This class holds whole application static content like scripts and styles.
1370-
Do not edit this file - use external tool to generate it.</Description>
1371-
<TimeCreated>63890,69938.115592</TimeCreated>
1372-
1373-
<Method name="Write">
1374-
<Description>
1375-
Write the contents of xData tag</Description>
1376-
<ClassMethod>1</ClassMethod>
1377-
<FormalSpec>Const:%String,Auth:%String</FormalSpec>
1378-
<ReturnType>%Status</ReturnType>
1379-
<Implementation><![CDATA[
1380-
set Auth = $get(Auth, "")
1381-
set obj = ##class(%Dictionary.CompiledXData).%OpenId("WebTerminal.StaticContent||"_Const)
1382-
quit:(obj = "") $$$OK
1383-
set xdata = obj.Data
1384-
set status=##class(%XML.TextReader).ParseStream(xdata, .textreader)
1385-
while textreader.Read() { if (textreader.NodeType="chars") {
1386-
if (Auth '= "") {// authorization key injection
1387-
write $REPLACE(textreader.Value, "createTerminal()", "createTerminal('"_Auth_"','"_%request.Get("NS")_"')")
1388-
} else {
1389-
write textreader.Value
1390-
}
1391-
} }
1392-
quit $$$OK
1393-
]]></Implementation>
1394-
</Method>
1395-
{{replace:themes}}
1396-
<XData name="Theme{{replace:themeName}}">
1397-
<Data><![CDATA[
1398-
<data>
1399-
<![CDATA[{{replace:themeData}}]]]]><![CDATA[>
1400-
</data>
1401-
]]></Data>
1402-
</XData>
1403-
{{replace:end}}
1404-
<XData name="html">
1405-
<Data><![CDATA[
1406-
<data>
1407-
<![CDATA[{{replace:html}}]]]]><![CDATA[>
1408-
</data>
1409-
]]></Data>
1410-
</XData>
1411-
1412-
<XData name="css">
1413-
<Data><![CDATA[
1414-
<data>
1415-
<![CDATA[{{replace:css}}]]]]><![CDATA[>
1416-
</data>
1417-
]]></Data>
1418-
</XData>
1419-
1420-
<XData name="js">
1421-
<Data><![CDATA[
1422-
<data>
1423-
<![CDATA[{{replace:js}}]]]]><![CDATA[>
1424-
</data>
1425-
]]></Data>
1426-
</XData>
1427-
</Class>
1428-
1429-
1430-
<Project name="WEBTerminal" LastModified="2015-12-06 12:10:07.906721">
1431-
<Items>
1432-
<ProjectItem name="WebTerminal.Engine" type="CLS"></ProjectItem>
1433-
<ProjectItem name="WebTerminal.Installer" type="CLS"></ProjectItem>
1434-
<ProjectItem name="WebTerminal.Router" type="CLS"></ProjectItem>
1435-
<ProjectItem name="WebTerminal.StaticContent" type="CLS"></ProjectItem>
1436-
</Items>
1437-
</Project>
14381129
</Export>

0 commit comments

Comments
 (0)