[closed] Adding a new enumeration value with server-side Java API in RTC
I have an attribute of type "enumeration list"; the enumeration is of type "database".
This attribute is automatically set by a follow-up action: the Java extension "calculates" the list to set in the attribute according to other attributes values, and then set the attribute with workItemWorkingCopy.setValue(attribute, list).
It works fine.
Anyway, it works only if the values in the list are already available in the enumeration (that is, in the database).
If the list contains a value that is not yet available, I should add it to the enumeration (that is, create a new entry in the database) before setting the attribute value.
Is it possible (using server-side Java API)?
My RTC version is 6.0.3.
My question looks very similar to this one: https://jazz.net/forum/questions/56133/how-to-programmatically-add-value-to-an-enumeration
Unfortunately, the thread does not have conclusive answer.
The question has been closed for the following reason: "The question is answered, right answer was accepted" by rschoon Jan 22, 10:00 a.m.
Accepted answer
Working Code:
@SuppressWarnings("unchecked") public void addEnumerationLiteral (IAttribute attribute, String identifierName, String identifierCode)
throws TeamRepositoryException { Enumeration enumeration= (Enumeration) enumerationService.resolveEnumeration(attribute); if (enumeration != null) { Enumeration enumCopy= (Enumeration) enumeration.getWorkingCopy(); Literal literal = EnumerationFactory.eINSTANCE.createLiteral(); com.ibm.team.workitem.common.internal.util.Utils.initNew(literal); IEnumeration<?> iEnumeration = this.workItemCommon.resolveEnumeration((IAttributeHandle) attribute.getItemHandle(), this.monitor); if (identifierCode==null) { identifierCode = getNextEnumerationIdentifierString(iEnumeration); } literal.setIdentifier(identifierCode); literal.setName(identifierName); literal.setSequenceValue(((Enumeration) enumeration).getLiterals().size()-1);((Enumeration) enumCopy).getLiterals().add(literal); if (((Enumeration) enumCopy).getLiterals().size() == 1) { ((Enumeration) enumCopy).setDefaultLiteralId(literal.getIdentifier()); } // asynchronous operation? enumerationService.update((Enumeration) enumCopy); } } public ILiteral getLastEnumerationLiteral (IEnumeration<?> enumeration) { ILiteral lastLiteral; List<?> literals = enumeration.getEnumerationLiterals(true); List<ILiteral> orderedLiterals = new ArrayList<ILiteral>(); for (Iterator<?> literalsIterator = literals.iterator(); literalsIterator.hasNext();) { // default: last position int orderedPosition = orderedLiterals.size(); ILiteral literal = (ILiteral) literalsIterator.next(); Hashtable<String, String> currentLiteralInfo = this.getLiteralStringInfo(literal); String currentLiteralNumberString = currentLiteralInfo.get("number"); Integer currentLiteralNumber = null; if (currentLiteralNumberString!=null) { currentLiteralNumber = Integer.parseInt(currentLiteralNumberString); } if (currentLiteralNumber!=null) { for (int i = 0; i<orderedLiterals.size(); i++) { Hashtable<String, String> orderedLiteralInfo = this.getLiteralStringInfo(orderedLiterals.get(i)); String orderedLiteralNumberString = orderedLiteralInfo.get("number"); Integer orderedLiteralNumber = null; if (orderedLiteralNumberString!=null) { orderedLiteralNumber = Integer.parseInt(orderedLiteralNumberString); } if (orderedLiteralNumber!=null) { if (currentLiteralNumber<orderedLiteralNumber) { orderedPosition = i; break; } } } orderedLiterals.add(orderedPosition, literal); } } lastLiteral = orderedLiterals.get(orderedLiterals.size()-1); return lastLiteral; } public String getNextEnumerationIdentifierString (IEnumeration<?> enumeration) { // avoid using when adding multiple identifiers all at once String nextIdentifierString = ""; ILiteral lastLiteral = this.getLastEnumerationLiteral(enumeration); Hashtable<String, String> lastLiteralInfo = this.getLiteralStringInfo(lastLiteral); String prefix = ""; String letter = ""; String numberString = null; prefix = lastLiteralInfo.get("prefix"); letter = lastLiteralInfo.get("letter"); numberString = lastLiteralInfo.get("number"); if ((!prefix.isEmpty()) && (!letter.isEmpty()) && (!numberString.isEmpty())) { Integer nextNumber = Integer.parseInt(numberString) + 2; nextIdentifierString = prefix + "." + letter + nextNumber.toString(); } return nextIdentifierString; } public Hashtable<String, String> getLiteralStringInfo (ILiteral literal) { Hashtable<String, String> literalStringInfo = new Hashtable<String, String>(); String prefix = ""; String letter = ""; Integer number = null;
// ibm.enumeration.waivertype.literal.l2 String literalRegularExpression = "^(.+)\.(\D+)(\d+)$"; Pattern literalPattern = Pattern.compile(literalRegularExpression); Matcher literalMatcher = literalPattern.matcher(literal.getIdentifier2().getStringIdentifier()); while (literalMatcher.find()) { prefix = literalMatcher.group(1); letter = literalMatcher.group(2); number = Integer.parseInt(literalMatcher.group(3)); literalStringInfo.put("prefix", prefix); literalStringInfo.put("letter", letter); literalStringInfo.put("number", number.toString()); }
return literalStringInfo; }
3 other answers
I have never seen code for that. It is obviously somehow possible, as the Eclipse client and the Web UI provide this. All you can do is to search for IEnumeration and hope to find something that hints how this can be done.
Comments
Ralph, actually, it worked.
I managed to add this enumeration by reusing the code in the addLiteralToPersistedEnumeration, with some modifications.
Just be aware that I suspect that the update method is asynchronous, as I noticed that, when I get the added identifier, later in the extension, it is sometimes null.
I solved this problem by surrounding the get method with a while cycle (I recheck the identifier value every 1000 ms, until it is not null).
Actually, it can take up to 10 seconds for the new identifier to be committed to the database.
Luca, you are most likely seeing a cash refresh delay. Another customer mentioned something here on the forum.
ps, you can use the "View HTM Source" button looks like a paper with <> on it to the top right" and add a [pre] [/pre] tag (with <, and .>) To make the code easier to read.
Hi All
@SuppressWarnings("unchecked") public static void addEnumerationLiteral(IAttribute attribute, String identifierName, String iconUrl) throws TeamRepositoryException { IEnumerationService enumerationService = (IEnumerationService) ((TeamRepository) CLMConnection.teamRepository) .getServiceInterface(IEnumerationService.class); Enumeration enumeration = (Enumeration) enumerationService.resolveEnumeration(attribute); if (enumeration != null) { Enumeration enumerationCopy = (Enumeration) enumeration.getWorkingCopy(); List<literal> literalsCopy = enumerationCopy.getLiterals(); Literal newLiteral = EnumerationFactory.eINSTANCE.createLiteral(); newLiteral.setIdentifier(getNewLiteralIdentifier(enumeration)); newLiteral.setName(identifierName); newLiteral.setSequenceValue(((Enumeration) enumeration).getLiterals().size() - 1); newLiteral.setIconUrl(iconUrl); literalsCopy.add(newLiteral); if (literalsCopy.size() == 1) { enumerationCopy.setDefaultLiteralId(newLiteral.getIdentifier()); } enumerationService.update(enumerationCopy); } } </literal>
public static String getNewLiteralIdentifier(Enumeration enumeration) { Literal lastLiteral = (Literal) enumeration.getLiterals().get(enumeration.getLiterals().size() - 1); String lastLiteralIdentifier = lastLiteral.getIdentifier(); return getNextId(lastLiteralIdentifier); }
public static String getNextId(String id) { String[] parts = id.split("(?=\d+$)", 2); return parts[0] + String.format("%0" + parts[1].length() + "d", Integer.parseInt(parts[1]) + 1); }
Comments
Hi Manju,
<label for="com_ibm_team_workitem_web_process_ui_internal_view_enumeration_AddEnumerationContent_3_enumNameField" style="color: rgb(102, 102, 102);"> Name: </label> | <input dojoattachpoint="enumNameField" id="com_ibm_team_workitem_web_process_ui_internal_view_enumeration_AddEnumerationContent_3_enumNameField" style="font-family: Arial, sans-serif; font-size: 9pt; margin: 0px; padding-bottom: 0px; padding-top: 0px; width: 441.378px;"> |
---|---|
<label for="com_ibm_team_workitem_web_process_ui_internal_view_enumeration_AddEnumerationContent_3_enumIdField" style="color: rgb(102, 102, 102);"> ID: </label> * | <input dojoattachevent="onchange:_handleIdChanged" dojoattachpoint="enumIdField" id="com_ibm_team_workitem_web_process_ui_internal_view_enumeration_AddEnumerationContent_3_enumIdField" style="font-family: Arial, sans-serif; font-size: 9pt; margin: 0px; padding-bottom: 0px; padding-top: 0px; width: 441.378px;"> |
<label for="com_ibm_team_workitem_web_process_ui_internal_view_enumeration_AddEnumerationContent_3_externalValueField" style="color: rgb(102, 102, 102);"> External URI: </label> | <input dojoattachevent="onchange:_handleExternalValueChanged" dojoattachpoint="externalValueField" id="com_ibm_team_workitem_web_process_ui_internal_view_enumeration_AddEnumerationContent_3_externalValueField" style="font-family: Arial, sans-serif; font-size: 9pt; margin: 0px; padding-bottom: 0px; padding-top: 0px; width: 441.378px;"> |
<label style="color: rgb(102, 102, 102);"> Choose where to store the Enumeration: </label> <input checked="checked" id="com_ibm_team_workitem_web_process_ui_internal_view_enumeration_AddEnumerationContent_3_enumStoreInProcessField" name="enumStore" style="font-family: Arial, sans-serif; font-size: 9pt; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding: 0px;" type="radio"> <label for="com_ibm_team_workitem_web_process_ui_internal_view_enumeration_AddEnumerationContent_3_enumStoreInProcessField" style="color: rgb(102, 102, 102); width: 100%;"> Process Specification (limits change permissions to project area maintainers) </label> <input dojoattachpoint="enumStoreInDbField" id="com_ibm_team_workitem_web_process_ui_internal_view_enumeration_AddEnumerationContent_3_enumStoreInDbField" name="enumStore" style="font-family: Arial, sans-serif; font-size: 9pt; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding: 0px;" type="radio"> <label for="com_ibm_team_workitem_web_process_ui_internal_view_enumeration_AddEnumerationContent_3_enumStoreInDbField" style="color: rgb(102, 102, 102); width: 100%;"> Database (allows to configure separate permissions to add new literals) </label> |
Hi @Mohammed,
Please do not answer with questions on an existing question. Create your own question. This is especially true, if the question is very old or already correctly answered.
Thanks.