I added this question to another Post (https://www.ariscommunity.com/users/hessphilipp/2010-02-04-symbol-attribute-object-aris-report-script#comment-27487), but it was an old post so I thought I would also add this New Post.
Wondering if anyone can help with a problem I am having. I have some very simple code (see below) to report (from Group or Model focus) Objects on Models including Model Path, Object Path, and Object Type which come from the ObjDefList. Where I am having a problem is I want to include the Object Symbol. I get the Symbols using the ObjOccList.
The problem is the Object Symbols come out in a DIFFERENT ORDER from th eloop than the Object Name and Type.
Is there are way to do this correctly? I have been doing a lot of searching and trying different things without success. It seems to have something to do with having to get some information from the Object Definition Method and some of the information from the Object Occurrence Method I think, but I can't figure it out. Any help would be much appreciated.
Thanks.
============================================================================
var output = Context.createOutputObject();
main();
function main() {
output.BeginTable(150, Constants.C_BLACK, Constants.C_WHITE, Constants.FMT_LEFT | Constants.FMT_ITALIC, 0);
output.TableRow();
output.TableCell("Model Path", 75, "Arial", 10, Constants.C_BLACK, Constants.C_LIGHT_BLUE, 0, Constants.FMT_LEFT | Constants.FMT_BOLD, 0);
output.TableCell("Model Name", 25, "Arial", 10, Constants.C_BLACK, Constants.C_LIGHT_BLUE, 0, Constants.FMT_LEFT | Constants.FMT_BOLD, 0);
output.TableCell("Object Path", 75, "Arial", 10, Constants.C_BLACK, Constants.C_LIGHT_BLUE, 0, Constants.FMT_LEFT | Constants.FMT_BOLD, 0);
output.TableCell("Object Name", 50, "Arial", 10, Constants.C_BLACK, Constants.C_LIGHT_BLUE, 0, Constants.FMT_LEFT | Constants.FMT_BOLD, 0);
output.TableCell("Object Type", 25, "Arial", 10, Constants.C_BLACK, Constants.C_LIGHT_BLUE, 0, Constants.FMT_LEFT | Constants.FMT_BOLD, 0);
output.TableCell("Object Symbol", 25, "Arial", 10, Constants.C_BLACK, Constants.C_LIGHT_BLUE, 0, Constants.FMT_LEFT | Constants.FMT_BOLD, 0);
var oModels = getRelevantModels();
for(var x = 0; x < oModels.length; x++)
{
var groupPath = oModels[x].Group().Path(Context.getSelectedLanguage());
var modelName = oModels[x].Name(Context.getSelectedLanguage());
var cModel = oModels[x]; // Current model
var aObjDefs = cModel.ObjDefList(); // All object definitions that have occurrences in the model
var ObjOcc = cModel.ObjOccList(); // Occurrences of All Object on model
for (var j = 0; j < aObjDefs.length; j++) // Loop through the object definitions
{
var oObjDef = aObjDefs[j]; // Current object definition
var sObjName = oObjDef.Name(Context.getSelectedLanguage()); // Name of current object
var sObjPath = oObjDef.Group().Path(Context.getSelectedLanguage()) // Group/Path of current object
var sObjType = oObjDef.Type() // Type of current object
var sObjSym = ObjOcc.SymbolName() // Default Symbol of current object
output.TableRow();
output.TableCell(groupPath.replace("Main group\\", ""), 75, "Arial", 10, Constants.C_BLACK, Constants.C_TRANSPARENT, 0, Constants.FMT_LEFT, 0);
output.TableCell(modelName, 25, "Arial", 10, Constants.C_BLACK, Constants.C_TRANSPARENT, 0, Constants.FMT_LEFT, 0);
output.TableCell(sObjPath, 75, "Arial", 10, Constants.C_BLACK, Constants.C_TRANSPARENT, 0, Constants.FMT_LEFT, 0);
output.TableCell(sObjName, 50, "Arial", 10, Constants.C_BLACK, Constants.C_TRANSPARENT, 0, Constants.FMT_LEFT, 0);
output.TableCell(sObjType, 25, "Arial", 10, Constants.C_BLACK, Constants.C_TRANSPARENT, 0, Constants.FMT_LEFT, 0);
output.TableCell(sObjSym, 25, "Arial", 10, Constants.C_BLACK, Constants.C_TRANSPARENT, 0, Constants.FMT_LEFT, 0);
} // for (var j...Object definitions
} // for (var x...Models
output.EndTable("Model Object Occurrences", 100, "Arial", 10, Constants.C_BLACK, Constants.C_BLACK, 0, Constants.FMT_LEFT | Constants.FMT_ITALIC, 0);
output.WriteReport();
}
function getRelevantModels() {
var selectedModels = ArisData.getSelectedModels();
if (selectedModels.length == 0) {
var selectedGroups = ArisData.getSelectedGroups();
for (var i = 0; i < selectedGroups.length; i++) {
var oRelevantModels = selectedGroups[i].ModelList(true);
if (oRelevantModels.length > 0) {
selectedModels = selectedModels.concat(oRelevantModels);
}
}
}
return selectedModels;
}
I don't really understand why you would want to iterate through the object definitions instead of the object occurrences with your "for (var j" loop.
Looking at ARIS from a database perspective, you have
- Models that stand in a 1:n relationship with occurrences
- occurrences that stand in a n:1 relationship with object definitions
So you correctly determine your model and after that I would
- iterate through the object occurrences
- on each object occurrence first call the .ObjDef() method to get the definition of the occurrence you're currently handling (and assign it to a variable that only exists within the loop-code-scope).
- Do all the other stuff you're already wrote inside your loop
With this approach you wouldn't need the line
var aObjDefs = cModel.ObjDefList();
at all.
Putting what I wrote into action it would look like
//...modelName...
var cModel = oModels[x]; // Current model
var objOccs = cModel.ObjOccList(); // Occurrences of All Object on model
for (var j = 0; j < objOccs.length; j++) // Loop through the object definitions
{
var oObjOcc = objOccs[j];
var oObjDef = oObjOcc.ObjDef(); // Current object definition
var sObjName = oObjDef.Name(Context.getSelectedLanguage()); // Name of current object
var sObjPath = oObjDef.Group().Path(Context.getSelectedLanguage()); // Group/Path of current object
var sObjType = oObjDef.Type(); // Type of current object
var sObjSym = oObjOcc.SymbolName(); // Default Symbol of current object
output.TableRow();
output.TableCell(groupPath.replace("Main group\\", ""), 75, "Arial", 10, Constants.C_BLACK, Constants.C_TRANSPARENT, 0, Constants.FMT_LEFT, 0);
output.TableCell(modelName, 25, "Arial", 10, Constants.C_BLACK, Constants.C_TRANSPARENT, 0, Constants.FMT_LEFT, 0);
output.TableCell(sObjPath, 75, "Arial", 10, Constants.C_BLACK, Constants.C_TRANSPARENT, 0, Constants.FMT_LEFT, 0);
output.TableCell(sObjName, 50, "Arial", 10, Constants.C_BLACK, Constants.C_TRANSPARENT, 0, Constants.FMT_LEFT, 0);
output.TableCell(sObjType, 25, "Arial", 10, Constants.C_BLACK, Constants.C_TRANSPARENT, 0, Constants.FMT_LEFT, 0);
output.TableCell(sObjSym, 25, "Arial", 10, Constants.C_BLACK, Constants.C_TRANSPARENT, 0, Constants.FMT_LEFT, 0);
} // for (var j...Object occurrences
I'm of course assuming your output.TableCells methods are fine. I didn't check those.
First I will explain why I need this and also know that I am New to Aris Administration and in particular Aris Scripting/Reporting. We are Baselining our Aris Artifacts/Repository. To this end we have placed certain Models into our Baseline and I just want to get Raw Data of the Model Name, Model Path, Objects Names (and Type) that exist on those Models, Path of where those Objects exist, Name of the Object, and the Symbol Name of those Objects. Having the raw data will allow me to slice and dice it as I see fit say in Excel to assist and work through our Baseline Cleanup.
So now you know why I need/want this type of report and I will say the code change you have indicated works which is great. Thank you.
The key piece of code was the:
var oObjDef = oObjOcc.ObjDef(); // Current object definition
Again remember I am quite new to this scripting. I was using Object Occurrences and Defintions "methods" separately as the Group Path information was associated witht the Object Definition and the Symbol Name was associated with the Object Occurrence from what I could figure out via some Aris Community postings and the Aris Help (http://myaris10now.softwareag.com/abs/help/en/script/ba/index.htm#scripthelp.html). You have combined the 2 in that particular line of code. So HOW WOULD I FIND OUT that you could do that oObjOcc.ObjDef() script statement? I could not figure that out from the sources I looked at.
Again thank you for all the help. It is much appreciated.
So HOW WOULD I FIND OUT that you could do that oObjOcc.ObjDef() script statement?
Trace what your script does and look up the relevant parts in the ARIS script help.
Javascript is a "weakly typed" / "untyped" programming language, hence ARIS itself can offer little help in regards to what you can and can't do while programming.
In your case (and to answer your question) you would do the tracing like
- With what does your program start? With models (either through ArisData.getSelectedModels() or selectedGroups[i].ModelList(true)). Looking at those methods, both say that their return value is Model.
- The Model class has a method called ObjOccList() which says that its return type is an array of ObjOcc
- ObjOcc have a method called ObjDef() that returns the associated ObjDef
My current philosophy in regards to ARIS scripting is that while scripting it is less important to know all the available methods (documented in the script help you linked). The amount of methods is simply to vast and methods also change from ARIS release to ARIS release.
Anyone can look up what they're currently able to do with their objects in the method help, so that's can't be the point in time where value is created.
Sure, over time you'll learn the most used methods and their required parameters by heart in order to massively accellerate your development workflow, but that's not what is important to write working reports.
So what's important instead?
It's a fundamental understanding of how ARIS entities (definitions, occurrences, attributes, models, groups, ARIS DBs, ...) are related with each other from a rational database perspective. Only with this understanding can you think about what should be documented in the script help and go look for exactly that.
That's also why I wrote relatively early in my previous comment
Looking at ARIS from a database perspective, you have
- Models that stand in a 1:n relationship with occurrences
- occurrences that stand in a n:1 relationship with object definitions
It's this type of understanding that you need in order to efficiently develop reports.
This type of knowledge of course also grants a lot of transformation potential.
Lets say you have to iterate through defintions instead of occurrences (to cut down on duplicate data - with iterating through occurrences you're of course able to list the same object definition paths multiple times if one object definition simply has multiple occurrences in the same model and you don't want that).
For each data row (representing an object definition) you instead want a column that could say something like "Automated function (x2), Manual function". This would indicate that in the current model the object definition of that row has three occurrences in total, 2 of which are executed automatically while one is executed manually.
This is of course possible. You start with what you already know
- Models that stand in a 1:n relationship with occurrences
- occurrences that stand in a n:1 relationship with object definitions
Therefore it should be possible to get all occurrences in a model, map them to their associated object defintitions and remove duplicates from the resulting definition list to get a list of unique object definitions. Those three steps ARIS conveniently combines into a single Model.ObjDefList() method.
Then you proceed
- Object definitions stand in a 1:n relationship with their respective occurrences
- Occurrences stand in a n:1 relationship with their model
Therefore it should be possible, given we have an object definition and a model, to filter the list of all definition occurrences for those that occur in the specified model.
You can either get all occurrences of a definition (ObjDef.ObjOccList()) and collect those you can prove that (Obj)Occ.Model() is equal to the model that you already have (with the Item.IsEqual(...) method) or rely on ARIS convenient ObjDef.OccList([yourModelGoesHere]) method to do all of that in a single line.
The rest is just counting the occurrence symbol names (ObjOcc.SymbolName()) with something like a java.util.Hashmap and making it presentable as a string, I won't go into detail of that since it's basic Java knowledge that can be acquired elsewhere.
In conclusion I highly recommend looking into (and even writing down) how you think ARIS entities are related with each other (similar to an UML diagram), and not fret too much about not being able to find something in the script help right away. It's mostly motivation (the thought "it should be possible") that allows you to look for specific things in the script help.
Thank you very much for the explanation. Many years ago, I came from a main frame programming background, but I have actually never used Java Script. Your explanation of the Methods and Classes actually is very helpful, and I think makes me feel much more comfortable going forward.
I totally agree with your statement about understanding the Aris Database Model. I think I have a reasonable understanding through the Admin work I have been doing to finally clean up our database/repository of about 6-7 years of unmanaged “junk” and actually create a Baseline.
It has been mentioned several times that if we only had an Aris Database Schema Model to reference it would be quite useful. Are you aware if there is any such documentation?
Once again though, I am very appreciative of all your help. With this report script working as I want it to I am that much closer to finalizing our Aris Baseline and implementing a proper Governance Process for Artifact Promotion to the Baseline.