Skip to content

Commit bf1a4ea

Browse files
Merge remote-tracking branch 'upstream/master'
2 parents 966bf88 + 9c656e3 commit bf1a4ea

19 files changed

+518
-180
lines changed

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,31 @@ An UML Class explorer for InterSystems Caché.
55
+ Build class diagrams;
66
+ Build diagrams for any package or subpackage;
77
+ Edit diagrams after build;
8+
+ Switch between strict UML notation and designed view;
89
+ Export diagrams as an image;
910
+ See Class methods, properties, parameters, SQL queries and more;
11+
+ See any keywords and related information by hovering over everything with pointer;
1012
+ View class methods code with syntax highlighting;
1113
+ Zoom in and out;
1214
+ Search on diagram or in class tree;
1315
+ Explore!
1416

1517
## Screenshots
1618

17-
![Demo](https://cloud.githubusercontent.com/assets/4989256/10561433/30415858-7531-11e5-97c6-6623d2b6ab30.png)
19+
![Demo](https://cloud.githubusercontent.com/assets/4989256/10566777/112646cc-75f9-11e5-95cc-3db82abf1706.png)
1820

1921
## Installation
2022

21-
To install latest Caché UML Explorer, you just need to import UMLExplorer package. Download the
23+
To install latest Caché Class Explorer, you just need to import ClassExplorer package. Download the
2224
archive from [latest releases](https://github.com/intersystems-ru/UMLExplorer/releases), and then import
23-
<code>Cache/CacheUMLExplorer-vX.X.X.xml</code> file.
25+
<code>Cache/CacheClassExplorer-vX.X.X.xml</code> file.
2426

2527
###### Web application
26-
Note that importing UMLExplorer.WebAppInstaller class will also create a /UMLExplorer application.
28+
Note that importing ClassExplorer.WebAppInstaller class will also create a /ClassExplorer application.
2729
If you want to create WEB application manually, please, do not import this class. Anyway, <b>
2830
importing this class requires %SYS permission.</b>
2931
## Usage
30-
Visit <code>[server domain and port]/UMLExplorer/</code> (slash at end required) to enter
32+
Visit <code>[server domain and port]/ClassExplorer/</code> (slash at end required) to enter
3133
application.
3234

3335
## Build

cache/projectTemplate.xml

Lines changed: 70 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2015.2 (Build 540)" ts="2015-04-28 19:50:48">
3-
<Class name="UMLExplorer.ClassView">
3+
<Class name="ClassExplorer.ClassView">
44
<Description>
5-
Cache UML Explorer vX.X.X/*build.replace:pkg.version*/
5+
Cache Class Explorer vX.X.X/*build.replace:pkg.version*/
66
Class contains methods that return structured classes/packages data.</Description>
7-
<TimeChanged>63830,81286.756889</TimeChanged>
7+
<TimeChanged>63844,1327.122337</TimeChanged>
88
<TimeCreated>63653,67019.989197</TimeCreated>
99

1010
<Method name="getAllNamespacesList">
@@ -45,33 +45,34 @@ Returns structured class tree with all classes available in current namespace</D
4545
set level = 1
4646
do objects.SetAt(resp, level)
4747
48-
4948
do classes.Execute()
5049
while (classes.Next()) {
5150
set name = classes.Data("Name")
5251
if ($EXTRACT(name, 1, 1) = "%") && ($NAMESPACE '= "%SYS") { continue }
5352
set parts = $LISTFROMSTRING(name, ".")
54-
set i = 0
55-
while (i < $LISTLENGTH(parts)) && ($LISTGET(lastParts, i + 1) = $LISTGET(parts, i + 1)) {
56-
set i = i + 1
53+
set level = 1
54+
while ((level < $LISTLENGTH(parts)) && ($LISTGET(lastParts, level) = ("/"_$LISTGET(parts, level)))) {
55+
set level = level + 1
5756
}
58-
set level = i + 1
5957
set resp = objects.GetAt(level)
6058
if (resp="") {
6159
set resp = ##class(%ZEN.proxyObject).%New()
62-
do objects.GetAt(level - 1).%DispatchSetProperty($LISTGET(parts, level - 1), resp)
60+
do objects.GetAt(level - 1).%DispatchSetProperty("/" _ $LISTGET(parts, level - 1), resp)
6361
do objects.SetAt(resp, level)
6462
}
6563
while ($LISTLENGTH(parts) > level) {
6664
set level = level + 1
6765
set resp = ##class(%ZEN.proxyObject).%New()
68-
do objects.GetAt(level - 1).%DispatchSetProperty($LISTGET(parts, level - 1), resp)
66+
do objects.GetAt(level - 1).%DispatchSetProperty("/" _ $LISTGET(parts, level - 1), resp)
6967
do objects.SetAt(resp, level)
7068
}
7169
if ($LISTLENGTH(parts) = level) {
7270
do resp.%DispatchSetProperty($LISTGET(parts, level), classes.Data("Hidden"))
7371
}
7472
set lastParts = parts
73+
for i=1:1:$LISTLENGTH(lastParts)-1 {
74+
set $LIST(lastParts, i) = "/"_$LISTGET(lastParts, i)
75+
}
7576
}
7677
7778
quit objects.GetAt(1)
@@ -87,26 +88,38 @@ Return structured data about class.</Description>
8788
<ReturnType>%ZEN.proxyObject</ReturnType>
8889
<Implementation><![CDATA[
8990
set classDefinition = ##class(%Dictionary.ClassDefinition).%OpenId(className)
91+
set compiledClassDefinition = ##class(%Dictionary.CompiledClass).%OpenId(className)
9092
if (classDefinition = "") || (oData.classes.%DispatchGetProperty(classDefinition.Name) '= "") quit ""
9193
9294
set oClass = ##class(%ZEN.proxyObject).%New()
9395
do oData.classes.%DispatchSetProperty(classDefinition.Name, oClass) // prevent from recursive setup
9496
set package = $LISTTOSTRING($LIST($LISTFROMSTRING(classDefinition.Name, "."), 1, *-1),".")
9597
set oProperties = ##class(%ZEN.proxyObject).%New()
9698
set oQueries = ##class(%ZEN.proxyObject).%New()
99+
set oIndices = ##class(%ZEN.proxyObject).%New()
97100
98-
set oClass.NAMESPACE = $NAMESPACE
99-
set oClass.SYSTEM = classDefinition.System
100-
set oClass.PROCEDUREBLOCK = classDefinition.ProcedureBlock
101-
set oClass.ABSTRACT = classDefinition.Abstract
102-
set oClass.FINAL = classDefinition.Final
103-
set oClass.HIDDEN = classDefinition.Hidden
104-
set oClass.classType = classDefinition.ClassType
105-
set oClass.serverOnly = classDefinition.ServerOnly // -
106101
set oClass.isDataType = classDefinition.ClientDataTypeIsDefined()
102+
set oClass.isOdbcType = classDefinition.OdbcTypeIsDefined()
103+
set oClass.isSoapBindingStyle = classDefinition.SoapBindingStyleIsDefined()
104+
set oClass.isSoapBodyUse = classDefinition.SoapBodyUseIsDefined()
105+
set oClass.isSqlCategory = classDefinition.SqlCategoryIsDefined()
106+
107+
set props = ##class(%Dictionary.ClassDefinition).%OpenId("%Dictionary.ClassDefinition")
108+
for j=1:1:props.Properties.Count() {
109+
set pname = props.Properties.GetAt(j).Name
110+
set:((pname '= "parent")
111+
&& ('props.Properties.GetAt(j).Private)
112+
&& ('$IsObject($PROPERTY(classDefinition, pname)))) $PROPERTY(oClass, pname) = $PROPERTY(classDefinition, pname)
113+
}
114+
if (oClass.TimeChanged) { set oClass.TimeChanged = $zdatetime(oClass.TimeChanged) }
115+
if (oClass.TimeCreated) { set oClass.TimeCreated = $zdatetime(oClass.TimeCreated) }
116+
if ((compiledClassDefinition '= "") && (compiledClassDefinition.ClassType '= "")) {
117+
set oClass.ClassType = compiledClassDefinition.ClassType // set class type from all inherited classes
118+
}
107119
120+
set oClass.Super = "" // do not quit with super at this moment
108121
if (oData.restrictPackage) && ('..inPackage(oData.basePackageName, package)) quit oClass
109-
set oClass.super = ..correctInheritance(oData, classDefinition, package)
122+
set oClass.Super = ..correctInheritance(oData, classDefinition, package) // now expand super names
110123
111124
set oClass.properties = oProperties
112125
set count = classDefinition.Properties.Count()
@@ -171,7 +184,20 @@ Return structured data about class.</Description>
171184
do oQueries.%DispatchSetProperty(q.Name, oProp)
172185
}
173186
174-
do ..collectInheritance(oData, oClass.super)
187+
#dim ind as %Dictionary.IndexDefinition
188+
set oClass.indices = oIndices
189+
set props = ##class(%Dictionary.ClassDefinition).%OpenId("%Dictionary.IndexDefinition")
190+
for i=1:1:classDefinition.Indices.Count() {
191+
set oProp = ##class(%ZEN.proxyObject).%New()
192+
set ind = classDefinition.Indices.GetAt(i)
193+
for j=1:1:props.Properties.Count() {
194+
set pname = props.Properties.GetAt(j).Name
195+
set:(pname '= "parent") $PROPERTY(oProp, pname) = $PROPERTY(ind, pname)
196+
}
197+
do oIndices.%DispatchSetProperty(ind.Name, oProp)
198+
}
199+
200+
do ..collectInheritance(oData, oClass.Super)
175201
176202
quit oClass
177203
]]></Implementation>
@@ -343,19 +369,19 @@ Returns structured package data</Description>
343369
</Class>
344370

345371

346-
<Project name="UMLExplorer" LastModified="2015-05-24 18:14:48.579613">
372+
<Project name="ClassExplorer" LastModified="2015-05-24 18:14:48.579613">
347373
<Items>
348-
<ProjectItem name="UMLExplorer.ClassView" type="CLS"></ProjectItem>
349-
<ProjectItem name="UMLExplorer.Router" type="CLS"></ProjectItem>
350-
<ProjectItem name="UMLExplorer.StaticContent" type="CLS"></ProjectItem>
351-
<ProjectItem name="UMLExplorer.WebAppInstaller" type="CLS"></ProjectItem>
374+
<ProjectItem name="ClassExplorer.ClassView" type="CLS"></ProjectItem>
375+
<ProjectItem name="ClassExplorer.Router" type="CLS"></ProjectItem>
376+
<ProjectItem name="ClassExplorer.StaticContent" type="CLS"></ProjectItem>
377+
<ProjectItem name="ClassExplorer.WebAppInstaller" type="CLS"></ProjectItem>
352378
</Items>
353379
</Project>
354380

355381

356-
<Class name="UMLExplorer.Router">
382+
<Class name="ClassExplorer.Router">
357383
<Description>
358-
REST interface for UMLExplorer</Description>
384+
REST interface for ClassExplorer</Description>
359385
<Super>%CSP.REST</Super>
360386
<TimeChanged>63697,73073.878177</TimeChanged>
361387
<TimeCreated>63648,30450.187229</TimeCreated>
@@ -365,8 +391,8 @@ REST interface for UMLExplorer</Description>
365391
<Routes>
366392
<Route Url="/" Method="GET" Call="Index"/>
367393
<Route Url="/index" Method="GET" Call="Index"/>
368-
<Route Url="/css/CacheUMLExplorer.css" Method="GET" Call="GetCss"/>
369-
<Route Url="/js/CacheUMLExplorer.js" Method="GET" Call="GetJs"/>
394+
<Route Url="/css/CacheClassExplorer.css" Method="GET" Call="GetCss"/>
395+
<Route Url="/js/CacheClassExplorer.js" Method="GET" Call="GetJs"/>
370396
<Route Url="/Test" Method="GET" Call="Test"/>
371397
<Route Url="/GetClassTree" Method="GET" Call="GetClassTree"/>
372398
<Route Url="/GetClassView" Method="GET" Call="GetClassView"/>
@@ -383,7 +409,7 @@ Method returns whole class tree visible in the current namespace.</Description>
383409
<ClassMethod>1</ClassMethod>
384410
<ReturnType>%Status</ReturnType>
385411
<Implementation><![CDATA[
386-
do ##class(UMLExplorer.ClassView).getClassTree(%request.Get("namespace")).%ToJSON(, "o")
412+
do ##class(ClassExplorer.ClassView).getClassTree(%request.Get("namespace")).%ToJSON(, "o")
387413
return $$$OK
388414
]]></Implementation>
389415
</Method>
@@ -420,7 +446,7 @@ Return the list of all namespaces</Description>
420446
<ClassMethod>1</ClassMethod>
421447
<ReturnType>%Status</ReturnType>
422448
<Implementation><![CDATA[
423-
do ##class(UMLExplorer.ClassView).getAllNamespacesList().%ToJSON(, "o")
449+
do ##class(ClassExplorer.ClassView).getAllNamespacesList().%ToJSON(, "o")
424450
return $$$OK
425451
]]></Implementation>
426452
</Method>
@@ -513,7 +539,7 @@ Issue an "304 Not Modified" status</Description>
513539
</Class>
514540

515541

516-
<Class name="UMLExplorer.StaticContent">
542+
<Class name="ClassExplorer.StaticContent">
517543
<Description>
518544
Cache UML Explorer vX.X.X/*build.replace:pkg.version*/ static content generator.
519545
Class contains methods that return JS/CSS/HTML data for single page application.</Description>
@@ -527,7 +553,7 @@ Write the contents of xData tag</Description>
527553
<FormalSpec>Const:%String</FormalSpec>
528554
<ReturnType>%Status</ReturnType>
529555
<Implementation><![CDATA[
530-
Set xdata = ##class(%Dictionary.CompiledXData).%OpenId("UMLExplorer.StaticContent||"_Const).Data
556+
Set xdata = ##class(%Dictionary.CompiledXData).%OpenId("ClassExplorer.StaticContent||"_Const).Data
531557
set status=##class(%XML.TextReader).ParseStream(xdata, .textreader)
532558
while textreader.Read() { if (textreader.NodeType="chars") { w textreader.Value } }
533559
return $$$OK
@@ -560,7 +586,7 @@ Write the contents of xData tag</Description>
560586
</Class>
561587

562588

563-
<Class name="UMLExplorer.WebAppInstaller">
589+
<Class name="ClassExplorer.WebAppInstaller">
564590
<Super>%Projection.AbstractProjection</Super>
565591
<TimeChanged>63696,65168.289869</TimeChanged>
566592
<TimeCreated>63696,64041.85537</TimeCreated>
@@ -587,14 +613,14 @@ This method is invoked when a class is compiled.</Description>
587613
set cspProperties("NameSpace") = ns
588614
set cspProperties("Description") = "A WEB application for Cache UML Explorer."
589615
set cspProperties("IsNameSpaceDefault") = 1
590-
set cspProperties("DispatchClass") = "UMLExplorer.Router"
591-
if ('##class(Security.Applications).Exists("/UMLExplorer")) {
592-
w !, "Creating WEB application ""/UMLExplorer""..."
593-
set tSC = ##class(Security.Applications).Create("/UMLExplorer", .cspProperties)
616+
set cspProperties("DispatchClass") = "ClassExplorer.Router"
617+
if ('##class(Security.Applications).Exists("/ClassExplorer")) {
618+
w !, "Creating WEB application ""/ClassExplorer""..."
619+
set tSC = ##class(Security.Applications).Create("/ClassExplorer", .cspProperties)
594620
if $$$ISERR(tSC) throw ##class(%Installer.Exception).CreateFromStatus(tSC)
595-
w !, "WEB application ""/UMLExplorer"" created."
621+
w !, "WEB application ""/ClassExplorer"" created."
596622
} else {
597-
w !, "WEB application ""/UMLExplorer"" already exists, so it is ready to use."
623+
w !, "WEB application ""/ClassExplorer"" already exists, so it is ready to use."
598624
}
599625
zn:ns'="%SYS" ns
600626
quit $$$OK
@@ -610,10 +636,10 @@ This method is invoked when a class is 'uncompiled'.</Description>
610636
<Implementation><![CDATA[
611637
set ns = $NAMESPACE
612638
zn:ns'="%SYS" "%SYS"
613-
if (##class(Security.Applications).Exists("/UMLExplorer")) {
614-
w !, "Deleting WEB application ""/UMLExplorer""..."
615-
do ##class(Security.Applications).Delete("/UMLExplorer")
616-
w !, "WEB application ""/UMLExplorer"" was successfully removed."
639+
if (##class(Security.Applications).Exists("/ClassExplorer")) {
640+
w !, "Deleting WEB application ""/ClassExplorer""..."
641+
do ##class(Security.Applications).Delete("/ClassExplorer")
642+
w !, "WEB application ""/ClassExplorer"" was successfully removed."
617643
}
618644
zn:ns'="%SYS" ns
619645
QUIT $$$OK

gulpfile.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ var banner = [
2323
" ** @author <%= pkg.author %>",
2424
" ** @version <%= pkg.version %>",
2525
" ** @license <%= pkg.license %>",
26-
" ** @see https://github.com/ZitRos/CacheUMLExplorer",
26+
" ** @see https://github.com/ZitRos/CacheClassExplorer",
2727
" **/",
2828
""
2929
].join("\n");
@@ -58,17 +58,17 @@ gulp.task("gatherLibs", ["clean"], function () {
5858
"web/jsLib/joint.layout.DirectedGraph.min.js"
5959
]))
6060
.pipe(stripComments({ safe: true }))
61-
.pipe(concat("CacheUMLExplorer.js"))
61+
.pipe(concat("CacheClassExplorer.js"))
6262
.pipe(replace(/ /g, "\\x0B"))
6363
.pipe(replace(/\x1b/g, "\\x1B"))
6464
.pipe(gulp.dest("build/web/js/"));
6565
});
6666

6767
gulp.task("gatherScripts", ["clean", "gatherLibs"], function () {
6868
return gulp.src("web/js/*.js")
69-
.pipe(concat("CacheUMLExplorer.js"))
69+
.pipe(concat("CacheClassExplorer.js"))
7070
.pipe(specialReplace())
71-
.pipe(wrap("CacheUMLExplorer = (function(){<%= contents %> return CacheUMLExplorer;}());"))
71+
.pipe(wrap("CacheClassExplorer = (function(){<%= contents %> return CacheClassExplorer;}());"))
7272
.pipe(uglify({
7373
output: {
7474
ascii_only: true,
@@ -78,15 +78,15 @@ gulp.task("gatherScripts", ["clean", "gatherLibs"], function () {
7878
preserveComments: "some"
7979
}))
8080
.pipe(header(banner, { pkg: pkg }))
81-
.pipe(addsrc.prepend("build/web/js/CacheUMLExplorer.js"))
82-
.pipe(concat("CacheUMLExplorer.js"))
81+
.pipe(addsrc.prepend("build/web/js/CacheClassExplorer.js"))
82+
.pipe(concat("CacheClassExplorer.js"))
8383
.pipe(replace(/\x1b/g, "\\x1B"))
8484
.pipe(gulp.dest("build/web/js/"));
8585
});
8686

8787
gulp.task("gatherCSS", ["clean"], function () {
8888
return gulp.src("web/css/*.css")
89-
.pipe(concat("CacheUMLExplorer.css"))
89+
.pipe(concat("CacheClassExplorer.css"))
9090
.pipe(postcss([ autoprefixer({ browsers: ["last 3 version"] }) ]))
9191
.pipe(minifyCSS({ keepSpecialComments: 0 }))
9292
.pipe(gulp.dest("build/web/css/"));
@@ -95,8 +95,8 @@ gulp.task("gatherCSS", ["clean"], function () {
9595
gulp.task("addHTMLFile", ["clean"], function () {
9696
return gulp.src("web/index.html")
9797
.pipe(htmlReplace({
98-
"css": "css/CacheUMLExplorer.css",
99-
"js": "js/CacheUMLExplorer.js"
98+
"css": "css/CacheClassExplorer.css",
99+
"js": "js/CacheClassExplorer.js"
100100
}))
101101
.pipe(gulp.dest("build/web/"));
102102
});
@@ -118,23 +118,23 @@ gulp.task("exportCacheXML", [
118118
.pipe(specialReplace())
119119
.pipe(replace(
120120
/\{\{replace:css}}/,
121-
function () { return fs.readFileSync("build/web/css/CacheUMLExplorer.css", "utf-8"); }
121+
function () { return fs.readFileSync("build/web/css/CacheClassExplorer.css", "utf-8"); }
122122
))
123123
.pipe(replace(
124124
/\{\{replace:js}}/,
125-
function () { return fs.readFileSync("build/web/js/CacheUMLExplorer.js", "utf-8"); }
125+
function () { return fs.readFileSync("build/web/js/CacheClassExplorer.js", "utf-8"); }
126126
))
127127
.pipe(replace(
128128
/\{\{replace:html}}/,
129129
function () { return fs.readFileSync("build/web/index.html", "utf-8"); }
130130
))
131-
.pipe(rename(function (path) { path.basename = "CacheUMLExplorer-v" + pkg["version"]; }))
131+
.pipe(rename(function (path) { path.basename = "CacheClassExplorer-v" + pkg["version"]; }))
132132
.pipe(gulp.dest("build/Cache"));
133133
});
134134

135135
gulp.task("zipRelease", ["exportCacheXML"], function () {
136136
return gulp.src(["build/**/*", "!build/web/**/*"])
137-
.pipe(zip("CacheUMLExplorer-v" + pkg["version"] + ".zip", {
137+
.pipe(zip("CacheClassExplorer-v" + pkg["version"] + ".zip", {
138138
comment: "Cache UML explorer v" + pkg["version"] + " by Nikita Savchenko\n\n" +
139139
"+ Cache folder holds XML file to import to InterSystems Cache.\n\n" +
140140
"For further information about installation and information, check README.md file."

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"name": "CacheUMLExplorer",
3-
"version": "1.5.1",
2+
"name": "CacheClassExplorer",
3+
"version": "1.8.2",
44
"description": "An UML Class explorer for InterSystems Caché",
55
"directories": {
66
"test": "test"
@@ -9,7 +9,7 @@
99
"devDependencies": {
1010
"autoprefixer-core": "^5.1.11",
1111
"express": "^5.0.0-alpha.1",
12-
"gulp": "^3.8.11",
12+
"gulp": "^3.9.0",
1313
"gulp-add-src": "^0.2.0",
1414
"gulp-clean": "^0.3.1",
1515
"gulp-concat": "^2.4.1",

0 commit comments

Comments
 (0)