How to fetch enum attributes using AttrBaseType - ibm-doors

I want to fetch enum attributes in a module using AttriBaseType and print it's elements.
Basically I want to know the usage of AttriBaseType in dxl.

For retrieving enum values, if you really want to use it explicitly, you can do it perhaps like this:
AttrType at
for at in current Module do {
print (at.name) " -- " (at.type) "\n"
AttrBaseType abt = at.type
if (abt == attrEnumeration) {
print "it is an " abt "\n"
int enumCount = at.size
int index
for (index = 0; index < enumCount; index++) {
// value, related number
print at.strings[index] ", " at.values[index] "\n"
}
print "\n"
}
}

Related

I can't assign array to string variable in flutter

for (i = 0; i < arr1.length - 1; i++) {
msg += arr1[i] + ",";
}
msg += arr1[i];
I want to throw the data from the above array into a string variable named msg with a comma between them. But I am getting an error as below. How can I fix.
_TypeError (type 'String' is not a subtype of type 'num' of 'other')
It depends of what type of data is store in the array. If integers, or whatever else, you need to tranform to a string, with the toString() method
So:
msg += arr1[i].tostring() + ",";
If mixed types, you can check type with something like this:
if (arr1[i] is int) {
msg += arr1[i].tostring() + ",";
}
if (arr1[i] is bool) {
if (arr1[i]) {
msg += "1,";
} else {
msg += "0,";
}
// And so on...
The error indicates that your arr1 are List<num>. The + function on num does not take a String which are the error you are getting.
I would recommend doing the following for creating your String since it will automatically call toString() on your num element and does also make the code smaller:
for (i = 0; i < arr1.length - 1; i++) {
msg += '${arr1[i]},';
}
msg += '${arr1[i]}';

Getting attributes without opening the module

Is there a way to get the attributes of a module without reading it?
I need to get that information for about 100 modules and it takes over 10 minutes if I have to read each module
I don't need to actually get the objects just the attributes available in the module
ModuleProperties should be faster. Try sth like this:
Item i = null
ModuleProperties mp = null
string sModuleAttribute = ""
string sError = ""
for i in project "/<myproject>" do {
if (type i == "Formal") {
sError = getProperties (moduleVersion module fullName i, mp)
if (null sError) {
for sModuleAttribute in mp do {
print fullName i "\t" sModuleAttribute "\t" mp.sModuleAttribute "\n"
}
} else {print sError "\n"}
delete mp
}
}
If you are also interested in the existence of attribute definitions for Objects, this might help
Item i = null
ModuleProperties mp = null
AttrDef ad = null
string sError = ""
for i in folder "/<myproject>" do {
if (type i == "Formal") {
sError = getProperties (moduleVersion module fullName i, mp)
if (null sError) {
for ad in mp do {
print fullName i "\t" ad.name "\t" ad.typeName "\t" ad.object "\t" ad.module "\n"
}
} else {print sError}
delete mp
}
}

Is there a way to view the last modified date of the the Object Text in DOORS?

I'm new to using DOORS and am trying to create a column/attribute that has the date of the last modification to the Object Text. I found the below code which uses "Last Modified On", but that that includes all attributes and I'm only concerned about the Object Text. Maybe there's a way to specifiy an attribute for this?
Date dMod
dMod = obj."Last Modified On"
dMod = dateAndTime(dMod)
display dMod ""
There's no such attribute on an attribute.
The only way to determine this is via the object's history. Below is the example script from DXL manual. The idea is to loop through the object's history until the history record's typeis modifyObjectand it's attrName equals 'Object Text'. Keep in mind, though, that the history in a module only goes back to the last baseline. So, you may have to browse through all baselines to find the history record you need. See Tony's "Smart History Viewer" at http://www.smartdxl.com/content/?page_id=125 for details.
// history DXL Example
/*
Example history DXL program.
Generate a report of the current Module's
history.
*/
// print a brief report of the history record
void print(History h) {
HistoryType ht = h.type
print h.author "\t" h.date "\t" ht "\t"
if (ht == createType ||
ht == modifyType ||
ht == deleteType) { // attribute type
print h.typeName
} else if (ht == createAttr ||
ht == modifyAttr ||
ht == deleteAttr) {
// attribute definition
print h.attrName
} else if (ht == createObject ||
ht == clipCopyObject ||
ht == modifyObject) { // object
print h.absNo
if (ht==modifyObject) {
// means an attribute has changed
string oldV = h.oldValue
string newV = h.newValue
print " (" h.attrName ":" oldV " -> " newV ")"
}
}
print "\n"
}
// Main program
History h
print "All history\n\n"
for h in current Module do print h
print "\nHistory for current Object\n\n"
for h in current Object do print h
print "\nNon object history\n\n"
for h in top current Module do print h

How to control the Index in a for statement in DXL

For some reason the DXL interpreter does not take into account the fact that I am decrementing i at the end of the for loop. I am trying to navigate through the arrObj[] array by changing the value of "i". I have some buttons that increment(for next object) and decrement(for previous object) the value respectively. Doing the same thing with a while loop crashes the application.
Is there any way to control the index or will DXL always remember the previous value and increment it (even if the user changes it's value within the code).
Here's a snippet from my code:
for i in 0:(iTotalObj-1) do
{
sAuxType = arrObj[i]."ObjectType"
sAuxNr = number(arrObj[i]) " "
sAuxObjTxt = arrObj[i]."Object Text"
print "\nAfter FOR:"i ""
if sAuxType == "Test-Case" then
{
set(testContent,"Index number: (" number(arrObj[i]) ") -> " arrObj[i]."Object Heading" "")
set(expectedResults, " ")
fillRow(sTesterName,sCfgSW,sCfgHW,arrObj[i])
block(dtbox)
}
if sAuxType == "Test-Step" then
{
set(testContent,"Index number: (" number(arrObj[i]) ") -> " arrObj[i]."Object Text" "")
set(expectedResults,richTextWithOle(arrObj[i]."ExpectedResult"))
fillRow(sTesterName,sCfgSW,sCfgHW,arrObj[i])
block(dtbox)
}
if sAuxType == "Test-Case-Description" then
{
set(testContent,"Index number: (" number(arrObj[i]) ") -> " arrObj[i]."Object Text" "")
set(expectedResults, "Please check the description throroughly")
fillRow(sTesterName,sCfgSW,sCfgHW,arrObj[i])
block(dtbox)
arrObj[i].("TestResult " iTR "") = "n/a"
arrObj[i].("FR " iTR "") = "n/a"
}
i--
print "\nAfter DECREMENT:"i ""
}
On the output box I'll get the following:
After FOR:0
After DECREMENT:-1
After FOR:1
After DECREMENT:0
After FOR:2
After DECREMENT:1
With that type of for loop I believe DOORS is forcing i to the next value in the set. You should be able to use this type of loop instead:
for(i=0; i<(iTotalObj-1); i++) {
...
}
This loop will allow you to manipulate i inside the loop.

JQL performance - natural sort for custom text field

I am struggling with a JQL query.
We have a custom field called 'Build Reported' which is a text field. It has values like '4.7.323H', '5.1.123L', '3.1.456E', etc.
I need to write a simple query that will give me all issues reported after the user-specified version.
JQL function prototype: searchIssues('Build Integrated', '>', '4.7.323B')
To do this, I am firing a JQL Query that gives me the Build Reported for all the issues, I then iterate through each issue and perform a char-by-char comparison to determine if the Build Reported version of the current issue is greater than the one specified by the user. This seems to take too long to execute since I have to retrieve all the issues from jira database.
Is there a faster way to achieve this? Here is what I have so far:
// Get all the arguments
java.util.List args = operand.getArgs();
CustomField cf = customFieldManager.getCustomFieldObjectByName((String)args.get(0));
Long cfID = cf.getIdAsLong();
String operator = (String)args.get(1);
String userVersion = (String)args.get(2);
String jiraVersion = "";
java.util.List issues;
Iterator issuesIterator;
Issue issue;
issues = getAllIssues(user, interestedInVersion, cfID);
issuesIterator = issues.iterator();
// Iterate over all the issues
while(issuesIterator.hasNext())
{
issue = (Issue)issuesIterator.next();
// Get the Build reported value
jiraVersion = (String)issue.getCustomFieldValue(cf);
if(jiraVersion != null &&
!jiraVersion.equals(""))
{
// Compare user-specified version to the one retrieved from database
if(compareVersions(jiraVersion, userVersion, operator))
{
// Add the issue to the result set
literals.add(new QueryLiteral(operand, issue.getId()));
}
}
}
// cfID is the ID for the custom field Build Reported
private java.util.List getAllIssues(User user, Long cfID) throws SearchException, ParseException
{
JqlQueryBuilder builder = JqlQueryBuilder.newBuilder();
builder.where().project("SDEV").and().customField(cfID).isNotEmpty();
Query query = builder.buildQuery();
SearchResults results = searchService.search(user, query, PagerFilter.getUnlimitedFilter());
return results.getIssues();
}
Please note that I do not have any other filters that I could use for the JQL Query Builder to help me reduce the size of the result set.
I found an alternative to the issue I described in my question. Instead of using JQL, I ended up firing a direct SELECT and this turned out to be way quicker. The function below is a part of the JQL Plugin. Here is the code:
This is what I ended up doing:
public java.util.List getValues(#NotNull QueryCreationContext queryCreationContext, #NotNull FunctionOperand operand, #NotNull TerminalClause terminalClause)
{
try
{
// User
User user = queryCreationContext.getUser();
// Args
java.util.List args = operand.getArgs();
CustomField cf = customFieldManager.getCustomFieldObjectByName((String)args.get(0));
Long cfID = cf.getIdAsLong();
String operator = (String)args.get(1);
String userVersion = (String)args.get(2);
// Locals
java.util.List literals = new java.util.LinkedList();
MutableIssue issue = null;
String issueId = "";
String jiraVersion = "";
// DB
Connection conn = null;
String url = "jdbc:jtds:sqlserver://*****:*****/jiradb";
String driver = "net.sourceforge.jtds.jdbc.Driver";
String userName = "*******";
String password = "*******";
String sqlQuery = null;
Statement statement = null;
ResultSet resultSet = null;
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url, userName, password);
// Get all the issues that has the custom field set
sqlQuery = " SELECT t2.id AS IssueId, t1.stringvalue AS JiraVersion " + "\n" +
" FROM jiradb.jiraschema.customfieldvalue t1 " + "\n" +
" INNER JOIN jiradb.jiraschema.jiraissue t2 " + "\n" +
" ON t1.issue = t2.id " + "\n" +
" WHERE t1.customfield = " + Long.toString(cfID) + " " + "\n" +
" AND t1.stringvalue IS NOT NULL " + "\n" +
" AND t1.stringvalue != '' " + "\n" +
" AND t2.pkey LIKE 'SDEV-%' ";
// Iterate over the result set
statement = conn.createStatement();
resultSet = statement.executeQuery(sqlQuery);
while (resultSet.next())
{
issueId = resultSet.getString("IssueId");
jiraVersion = resultSet.getString("JiraVersion");
// Compare the version from jira with the user provided version
// This is my own function that does char-by-char comparison
if(compareVersions(jiraVersion, userVersion, operator))
{
// Get the issue object to add to the result
issue = ComponentManager.getInstance().getIssueManager().getIssueObject(Long.parseLong(issueId));
// Add the issue to the result
literals.add(new QueryLiteral(operand, issue.getId()));
}
}
// Return all the matching issues here
return literals;
}
catch(Exception e)
{
// Exception handling
}
return null;
}
And this is how the plugin is used:
issue in searchIssues('Build Reported', '>', '5.1.104');

Resources