cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - New to the community? Learn how to post a question and get help from PTC and industry experts! X

Windchill Customization(Giving constraint to an attribute)

KD
4-Participant
4-Participant

Windchill Customization(Giving constraint to an attribute)

Hi everybody !

I am very new to this forum & very beginner to windchill 10.1.

Is this possible to add constraint to an attribute through program.

(ex. SingleValuedConstraint, LegalValueList)

1 ACCEPTED SOLUTION

Accepted Solutions
KD
4-Participant
4-Participant
(To:vbrenaut)

Using this code has one demerit

The OOTB processor can’t persist the value so you have to write a custom processor also.

View solution in original post

22 REPLIES 22
MatthewKnight
4-Participant
(To:KD)

For WC 9.1:

In my experience, manipulating the AttributeContainer of the IBAHolder and the related View objects is overly complex. That statement's probably debatable, but directly manipulating the Persistable constraints seems much easier.

Here's an example of creating a DiscreteSet constraint:

Object values[] = new Object[]{"Blue","Red","Green"};

DiscreteSet ds = new DiscreteSet(values);

WTTypeDefinition td = ....

AttributeDefinition ad = ....;

TypeSingleAttrConstraint constraint = new TypeSingleAttrConstraint();

constraint.setTypeDefinition(td);

constraint.setAttributeDefinition(AttributeDefinitionReference.newAttributeDefinitionReference((AbstractAttributeDefinition)ad));

constraint.setBindingRuleClassName(SingleAttributeConstraintBindingRule.class.getName());

constraint.setEnforcementRuleClassName(DiscreteSetConstraint.class.getName());

constraint.setEnforcementRuleData(ds);

constraint = save/insert(constraint);

You may want to clear/reset any applicable cache afterwards.

KD
4-Participant
4-Participant
(To:MatthewKnight)

Thanks Matthew.

I am in 10.1 and what I want to do is suppose there is one soft attribute of Document named "New". Now I need a dropdown box in the UI with some value like the attached picture and again that attribute will be a multi valued attribute.

So, how to do that?

I want to give the value programmatically cause those values will come from a txt file.Untitled.png

KD
4-Participant
4-Participant
(To:KD)

Any suggestion please

ChiragSuthar
5-Regular Member
(To:KD)

Use Lov type attribute and give values seperated by "|".

KD
4-Participant
4-Participant
(To:ChiragSuthar)

but that will be from UI ,my value is coming from a text file so I have to give value programmatically

tstacy
1-Newbie
(To:KD)

Have you considered using a DataUtility to read your text file and populate the drop-down when the UI is rendered?

KD
4-Participant
4-Participant
(To:tstacy)

Yes I tried that I used the StringInputComponent to make a dropdown list but I have to again make it a MultiValuedAttribute there I am stuck

MatthewKnight
4-Participant
(To:KD)

Does the stuff I gave you not work in 10?

tstacy
1-Newbie
(To:KD)

We defined our own MultiSelectDisplayComponent and renderer. Then we used it in a Data Utility to display a multi-select list of values.

MultiSelectDisplayComponent.java:

import com.ptc.core.components.rendering.guicomponents.*;

import java.util.ArrayList;

public class MultiSelectDisplayComponent extends AttributeGuiComponent implements PrintableComponent

{

private static final long serialVersionUID = 1L;

String attributeName;

int numberOfDisplayLines = 0;

ArrayList<String> keyValues;

ArrayList<String> displayValues;

ArrayList<String> selectedValues;

public MultiSelectDisplayComponent( String attrName, ArrayList<String> keys, ArrayList<String> displayV, ArrayList<String> selectedV, int numLines)

{

attributeName = attrName;

keyValues = keys;

numberOfDisplayLines = numLines;

selectedValues = selectedV;

displayValues = displayV;

setRenderer(new MultiSelectDisplayComponentRenderer());

}

public String getPrintableValue()

{

return "";

}

}

----------------------------------------------------------------

MultiSelectDisplayComponentRenderer.java:

import com.ptc.core.components.rendering.*;

import java.io.PrintWriter;

import java.util.Vector;

import wt.util.WTContext;

import java.lang.reflect.Method;

import wt.util.WTStringUtilities;

import wt.fc.EnumeratedType;

public class MultiSelectDisplayComponentRenderer extends AbstractRenderer

{

private static final long serialVersionUID = 1L;

public MultiSelectDisplayComponentRenderer()

{

}

protected void renderObject(Object obj, PrintWriter pw, RenderingContext rc)

throws RenderingException

{

renderObject((MultiSelectDisplayComponent)obj, pw, rc);

}

protected void renderObject(MultiSelectDisplayComponent comp, PrintWriter pw, RenderingContext rc)

throws RenderingException

{

write(pw, buildMultiSelectComponent(comp));

}

protected String buildMultiSelectComponent(MultiSelectDisplayComponent dispComp)

{

//System.out.println("+++ In MultiSelectDisplayComponentRenderer.buildMultiSelectComponent()");

String htmlString;

Vector<String> theList = new Vector<String>();

String s1 = null;

int numLines = dispComp.numberOfDisplayLines;

if (numLines <= 1 ) numLines = 4;

if (dispComp.selectedValues != null) {

for (int j=0; j<dispComp.selectedValues.size(); j++){

theList.add(dispComp.selectedValues.get(j));

}

}

htmlString = "<select ";

htmlString = htmlString + "name= \"" + dispComp.attributeName + "\" id = \"" + dispComp.attributeName + "\"";

if (dispComp.isRequired()) {

htmlString = htmlString + " class = \"required \"";

}

htmlString = htmlString + " multiple size=" + numLines;

htmlString = htmlString + ">\n";

try {

for (int k=0;k< dispComp.keyValues.size(); k++) {

if ( dispComp.selectedValues == null ) {

String stringV = dispComp.keyValues.get(k);

String displayV = dispComp.displayValues.get(k);

htmlString +=" <OPTION VALUE=\"" + stringV + "\">" + displayV + "\n";

} else {

boolean selected;

String stringV = dispComp.keyValues.get(k);

String displayV = dispComp.displayValues.get(k);

if ( dispComp.selectedValues != null) {

selected = dispComp.selectedValues.contains(stringV);

} else {

selected = false;

}

if (selected) {

htmlString +=" <OPTION VALUE=\"" + stringV + "\" selected>" + displayV + "\n";

} else {

htmlString +=" <OPTION VALUE=\"" + stringV + "\">" + displayV + "\n";

}

}

}

} catch ( Exception ex ) {

ex.printStackTrace();

}

htmlString += "</select>";

//System.out.println("+++ Leaving MultiSelectDisplayComponentRenderer.buildMultiSelectComponent()");

return htmlString;

}

protected boolean isValidForObject(Object obj)

{

return obj instanceof MultiSelectDisplayComponent;

}

}

------------------------------------------------------------------

Usage in Data Utility.getDataValue method:

MultiSelectDisplayComponent multiSelectComp = new MultiSelectDisplayComponent(compId, keyValues, displayValues, selectedValues, listSize);

multiSelectComp.setRequired(isRequired);

return multiSelectComp;

KD
4-Participant
4-Participant
(To:tstacy)

Theresa I implement your solution It working fine as a multiselect thanks for that ..

But what I want is a littile different .

I need the functionality of MultiValued attribute like that plus or minus button

Thanks everyone for your answers finally I got the answer after backtracking the OOTB functionality.

vbrenaut
1-Newbie
(To:KD)

Hello,

I ve the same problem to resolve. Could you explain to me how you succeed to get a multi valuated component with suggested list? backtracking OOTB functionality? Tank's a lot. I am on the PDMLink 10.4.

KD
4-Participant
4-Participant
(To:vbrenaut)

Using this code has one demerit

The OOTB processor can’t persist the value so you have to write a custom processor also.

rmk
1-Newbie
1-Newbie
(To:KD)

Hi Kaushik,

Thanks for sharing the code. Please share the processor src too. this will help a lot.

Thanks in Advance.

KD
4-Participant
4-Participant
(To:rmk)

Hi,

I assume that the IBA’s internal name is VendorName and it’s only in a specific subtype of WTDocument whose

internal name is com.ptc.Agenda.

For Create Mode :-

package ext.customization.processor;

import java.util.Arrays;

import java.util.Enumeration;

import java.util.HashSet;

import java.util.Iterator;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import wt.doc.WTDocument;

import wt.fc.ObjectReference;

import wt.fc.Persistable;

import wt.fc.PersistenceHelper;

import wt.folder.Folder;

import wt.util.WTException;

import com.ptc.core.components.beans.ObjectBean;

import com.ptc.core.components.forms.FormResult;

import com.ptc.core.lwc.server.LWCNormalizedObject;

import com.ptc.core.meta.common.TypeIdentifierHelper;

import com.ptc.core.meta.common.UpdateOperationIdentifier;

import com.ptc.netmarkets.util.beans.NmCommandBean;

import com.ptc.windchill.enterprise.doc.forms.CreateDocFormProcessor;

import com.ptc.windchill.wp.delivery.DeliveryRecord;

public class CustomDocProcessor extends CreateDocFormProcessor

{

@SuppressWarnings({ "rawtypes", "unchecked" })

@Override

public FormResult postProcess(NmCommandBean paramNmCommandBean,

List<ObjectBean> paramList) throws WTException

{

/* Taking the object of WTDocument which is created form the CreateDocFromProcessor*/

WTDocument localWTDocument = null;

for (Iterator localIterator = paramList.iterator(); localIterator.hasNext(); )

localWTDocument = (WTDocument)(((ObjectBean)localIterator.next()).getObject());

try{ /* Checking whether the WTDocument is of desired subtype */

if(( TypeIdentifierHelper.getType(localWTDocument).toString().equals("WCTYPE|wt.doc.WTDocument|

com.ptc.Agenda ")))//internal name of your subtype

{

HttpServletRequest req = paramNmCommandBean.getRequest();

Enumeration em = req.getParameterNames();

String temp = null;

while(em.hasMoreElements())

{

String name="VendorName";//internal name of your iba

String old = "old";

temp = em.nextElement().toString();

if(temp.contains(name) && !temp.endsWith(old))

break;

}

//Giving value to the soft attribute

LWCNormalizedObject obj = new LWCNormalizedObject(localWTDocument,null,null,new

UpdateOperationIdentifier());

//removing duplicate value

obj.load("VendorName");

obj.set("VendorName",(String[])new HashSet( Arrays.asList( req.getParameterValues(temp) )

).toArray( new String[]{} ));

/*persisting the value of IBA after removing duplicate value*/

obj.apply();

PersistenceHelper.manager.modify(localWTDocument);

}

}

catch(WTException e)

{

e.printStackTrace();

}

// TODO Auto-generated method stub

return super.postProcess(paramNmCommandBean, paramList);

}

}

KD
4-Participant
4-Participant
(To:KD)

For Edit

package ext.customization.processor;

import java.util.*;

import javax.servlet.http.HttpServletRequest;

import wt.doc.WTDocument;

import wt.fc.PersistenceHelper;

import wt.util.WTException;

import com.ptc.core.components.beans.ObjectBean;

import com.ptc.core.components.forms.EditWorkableFormProcessor;

import com.ptc.core.components.forms.FormResult;

import com.ptc.core.lwc.server.LWCNormalizedObject;

import com.ptc.core.meta.common.TypeIdentifierHelper;

import com.ptc.core.meta.common.UpdateOperationIdentifier;

import com.ptc.netmarkets.util.beans.NmCommandBean;

public class CustomEditDocProcessor extends EditWorkableFormProcessor

{

@SuppressWarnings("rawtypes")

@Override

public FormResult postProcess(NmCommandBean paramNmCommandBean,

List<ObjectBean> paramList) throws WTException

{

WTDocument localWTDocument = null;

for (Iterator localIterator = paramList.iterator(); localIterator.hasNext(); )

localWTDocument = (WTDocument)(((ObjectBean)localIterator.next()).getObject());

/* Taking the object of WTDocument which is created form the EditWorkableFormProcessor*/

try

{

if( (

TypeIdentifierHelper.getType(localWTDocument).toString().equals("WCTYPE|wt.doc.WTDocument|com.ITCINFOTECH.VendorPart")))

{

HttpServletRequest req = paramNmCommandBean.getRequest();

Enumeration em = req.getParameterNames();

String temp = null;

while(em.hasMoreElements())

{

String name="VendorName";

String old = "old";

temp = em.nextElement().toString();

if(temp.contains(name) && !temp.endsWith(old))

break;

}

//Giving value to the soft attribute

LWCNormalizedObject obj = new LWCNormalizedObject(localWTDocument,null,null,new

UpdateOperationIdentifier());

@SuppressWarnings({ "unchecked" })

String[] s = (String[])new HashSet( Arrays.asList( req.getParameterValues(temp) ) ).toArray( new

String[]{} );

List<String> list = new ArrayList<String>();

for(String str : s)

{

if(str != null && str.length() > 0)

{

list.add(str);

}

}

s = list.toArray(new String[list.size()]);

/* After removing any blank string from String array */

obj.load("VendorName");

obj.set("VendorName",s);

obj.apply();

PersistenceHelper.manager.modify(localWTDocument);

}

}

catch(WTException e)

{

e.printStackTrace();

}

// TODO Auto-generated method stub

return super.postProcess(paramNmCommandBean, paramList);

}

}

Thanks And Regards,

Kaushik

Hi Kaushik,

Is there a way to fetch all the attributes for a given subtype?

Is there a way to pull the metadata of the fetched attribute?

For example, i have a subtype of "CustomerExperience" object and many attributes configured on this subtype.

I am trying to fetch all the MBA(Model Based Attributes) and IBA(Instances Based Attributes), and after that fetch all the constraints,default values, datatype etc.. i.e metadata of the attribute

Thanks

RK

KD
4-Participant
4-Participant
(To:rbhagavatula)

Hi RK,

To fetch all the IBA's of a given softtype use below method.

public static ArrayList<String> getIBAInformationForSoftType(

String internalName) {

ArrayList<String> logicalNames = new ArrayList<String>();

LogicalIdentifierFactory factory = new LogicalIdentifierFactory();

TypeIdentifier ti = factory.newWCTypeIdentifier(internalName);

GetSoftSchemaAttributesCommand command = new GetSoftSchemaAttributesCommand();

command.setType_id(ti);

try {

command = (GetSoftSchemaAttributesCommand) command.execute();

AttributeTypeIdentifierSet atis = command.getAttributes();

Iterator iter = atis.iterator();

while (iter.hasNext()) {

AttributeTypeIdentifier ati = (AttributeTypeIdentifier) iter

.next();

if (!ati.getAttributeName().equals("view")) {

try {

String name = ati.toLogicalForm();

logicalNames.add(name);

System.out.println("Logical identifier of the IBA :- " + name);

} catch (Exception e) {

e.printStackTrace();

}

}

}

} catch (CommandException e) {

e.printStackTrace();

}

return logicalNames;

}

Thanks,

Kaushik

Hi Kaushik,

Happy new year. Thanks you so much for repying.

I tried the snippet however it fetches only the IBAs. I am trying to fetch both IBAs and MBAs, i.e. all attributes(instance based and model based). Any furthur updates on all attributes is really helpful.

Thanks

RK

KD
4-Participant
4-Participant
(To:rbhagavatula)

Hello Ramakrishna,

Happy new year to you to.

For MBA try below snippet.

public static ArrayList<String> getIBAInformationForHardType(String className) {

ArrayList<String> attributes = new ArrayList<String>();

LogicalIdentifierFactory factory = new LogicalIdentifierFactory();

TypeIdentifier ti = factory.newWCTypeIdentifier(className);

GetHardSchemaAttributesCommand command = new GetHardSchemaAttributesCommand();

command.setType_id(ti);

try {

command = (GetHardSchemaAttributesCommand) command.execute();

AttributeTypeIdentifierSet atis = command.getAttributes();

Iterator iter = atis.iterator();

while(iter.hasNext()){

AttributeTypeIdentifier ati = (AttributeTypeIdentifier) iter.next();

if(!ati.getAttributeName().equals("view")){

String name = ati.getAttributeName();

System.out.println(name);

attributes.add(name);

}

}

} catch (CommandException e) {

e.printStackTrace();

}

return attributes;

}

------------------------------------------------------------------------------

getIBAInformationForHardType("wt.doc.WTDocument")

Thanks and Regards,

Kaushik

KD_9882341
1-Newbie
(To:KD)

I also need to add plus minus sign to multiValuedAttribute, Please provide the code of how you have done.

BjoernRueegg
17-Peridot
(To:KD)

Hi, in 10.2 you have this OOTB, called "External Enumerated Value List". There you can pull the values from a text file or even from a DB like ERP.

wcbru_10_2_M020.png
Happy New Year!
Björn

Hi Kaushik,

I have one doubt. I have one custom column. I want to publish the value of distribution target there. How can I get the value of Distribution target name or number in that column?

I mean, how can I fetch the data of Distribution target IBA there?

Thanks,

Sakil

Top Tags