目录
一、需求说明
在Windchill的后端开发中,查询数据库经常会使用到ConfigSpec进行条件的查询。而OOTB提供的一些ConfigSpec不能满足落地项目中实际的一些场景,而这些场景恰恰是经常需要调用使用的。
故以此为需求为引,作为此文章示例的出发点。
此示例中,主要是封装了查询物料时,视图及多状态的一个多条件的ConfigSpec。这大大提升了开发当中调用时的便利性。
二、代码示例
package ext.test.optimalize.model;
import java.beans.PropertyChangeEvent;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import wt.fc.ObjectVector;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.identity.IdentityFactory;
import wt.introspection.PropertyDisplayName;
import wt.lifecycle.LifeCycleManaged;
import wt.lifecycle.State;
import wt.query.OrderBy;
import wt.query.QueryException;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.util.WTException;
import wt.util.WTInvalidParameterException;
import wt.util.WTPropertyVetoException;
import wt.vc.Iterated;
import wt.vc.config.ConfigException;
import wt.vc.config.ConfigSpec;
import wt.vc.config.LatestConfigSpec;
import wt.vc.config.RelationalConfigSpec;
import wt.vc.config.RelationalConfigSpecBridge;
import wt.vc.config.ViewConfigSpec;
import wt.vc.config.ViewManageableOrderByVariation1Primitive;
import wt.vc.config.ViewManageableOrderByVariation2Primitive;
import wt.vc.views.Variation1;
import wt.vc.views.Variation2;
import wt.vc.views.View;
import wt.vc.views.ViewManageable;
import wt.vc.views.ViewReference;
import wt.vc.wip.WorkInProgressHelper;
import wt.vc.wip.WorkInProgressState;
import wt.vc.wip.Workable;
import com.ptc.windchill.annotations.metadata.GenAsObjectMappable;
import com.ptc.windchill.annotations.metadata.GeneratedProperty;
import com.ptc.windchill.annotations.metadata.GetAccess;
import com.ptc.windchill.annotations.metadata.PropertyAccessors;
import com.ptc.windchill.annotations.metadata.SupportedAPI;
@GenAsObjectMappable(interfaces = { ConfigSpec.class }, properties = {
@GeneratedProperty(name = "lifeCycleStates", type = State[].class, supportedAPI = SupportedAPI.PUBLIC, javaDoc = "If set, ONLY those WTParts at this particular state are returned.", accessors = @PropertyAccessors(setExceptions = {})),
@GeneratedProperty(name = "workingIncluded", type = boolean.class, initialValue = "true", supportedAPI = SupportedAPI.PUBLIC, javaDoc = "If true, include any working copies I may have.", accessors = @PropertyAccessors(setExceptions = {})),
@GeneratedProperty(name = "viewRef", type = ViewReference.class, supportedAPI = SupportedAPI.PRIVATE, accessors = @PropertyAccessors(getAccess = GetAccess.PRIVATE, setExceptions = {})),
@GeneratedProperty(name = "variation1", type = Variation1.class, supportedAPI = SupportedAPI.PUBLIC, javaDoc = "If set, only those objects assigned to the variation1 are returned. If no WTParts match the variation1, other variation1s are checked from the bottom of the hierarchy up(until there is either at least one match or no parent). WTParts with null variation1 are checked last. If this is not set only WTParts with null variation1 will be returned."),
@GeneratedProperty(name = "variation2", type = Variation2.class, supportedAPI = SupportedAPI.PUBLIC, javaDoc = "If set, only those objects assigned to the variation2 are returned. If no WTParts match the variation2, other variation2s are checked from the bottom of the hierarchy up(until there is either at least one match or no parent). WTParts with null variation2 are checked last. If this is not set only WTParts with null variation2 will be returned.") })
public class WTPartMultiStateConfigSpec extends _WTPartMultiStateConfigSpec {
public static final String VIEW = "view";
static final long serialVersionUID = 1L;
private boolean isPrimaryClassViewManageable = true;
public View getView() {
return this.viewRef == null ? null : (View) this.viewRef.getObject();
}
public void setView(View paramView) throws WTPropertyVetoException {
if ((paramView != null) && (!PersistenceHelper.isPersistent(paramView))) {
Object[] arrayOfObject1 = { new PropertyDisplayName(CLASSNAME,
"view") };
throw new WTPropertyVetoException("wt.part.partResource", "1",
arrayOfObject1, new PropertyChangeEvent(this, "view",
this.viewRef == null ? null : IdentityFactory
.getDisplayIdentifier(this.viewRef
.getObject()),
paramView.getIdentity()));
}
try {
this.viewRef = (paramView == null ? null : ViewReference
.newViewReference(paramView));
} catch (WTException localWTException) {
Object[] arrayOfObject2 = { new PropertyDisplayName(CLASSNAME,
"view") };
throw new WTPropertyVetoException("wt.part.partResource",
localWTException.getLocalizedMessage(), arrayOfObject2,
new PropertyChangeEvent(this, "view",
this.viewRef == null ? null : IdentityFactory
.getDisplayIdentifier(this.viewRef
.getObject()),
paramView.getIdentity()));
}
}
public static WTPartMultiStateConfigSpec newWTPartMultiStateConfigSpec()
throws WTException {
WTPartMultiStateConfigSpec localWTPartStandardConfigSpec = new WTPartMultiStateConfigSpec();
localWTPartStandardConfigSpec.initialize();
return localWTPartStandardConfigSpec;
}
protected void initialize() throws WTException {
}
public static WTPartMultiStateConfigSpec newWTPartMultiStateConfigSpec(
View paramView, State... paramStates) throws WTException {
WTPartMultiStateConfigSpec localWTPartStandardConfigSpec = new WTPartMultiStateConfigSpec();
localWTPartStandardConfigSpec.initialize(paramView, paramStates);
return localWTPartStandardConfigSpec;
}
protected void initialize(View paramView, State[] paramState)
throws WTException {
try {
setView(paramView);
} catch (WTPropertyVetoException localWTPropertyVetoException) {
throw new WTException(localWTPropertyVetoException);
}
setLifeCycleStates(paramState);
}
public static QuerySpec appendSearchCriteria(QuerySpec paramQS,
State... states) throws WTException {
if (states == null || states.length == 0) {
return paramQS;
}
String[] stateStrArray = new String[states.length];
for (int i = 0; i < stateStrArray.length; i++) {
stateStrArray[i] = states[i].toString();
}
QuerySpec localeQs = (QuerySpec) paramQS.clone();
if (!LifeCycleManaged.class.isAssignableFrom(localeQs.getClassAt(0))) {
Object[] localObject = new Object[] { LifeCycleManaged.class
.getName() };
throw new WTInvalidParameterException(
"wt.vc.config.configResource", "0", localObject);
}
if ((paramQS.getConditionCount() > 0)
&& localeQs.getWhere().endsWith(")")) {
localeQs.appendAnd();
localeQs.appendWhere(new SearchCondition(localeQs.getClassAt(0),
"state.state", stateStrArray, true), new int[] { 0 });
}
return localeQs;
}
public QuerySpec appendSearchCriteria(QuerySpec paramQuerySpec)
throws WTException, QueryException {
QuerySpec localQuerySpec = new LatestConfigSpec()
.appendSearchCriteria(paramQuerySpec);
if (!isWorkingIncluded()) {
localQuerySpec.appendAnd();
localQuerySpec.appendWhere(new SearchCondition(Workable.class,
"checkoutInfo.state", "<>", WorkInProgressState.WORKING),
new int[] { 0 });
}
if (!localQuerySpec.getPrimaryClass().getName()
.equalsIgnoreCase("wt.part.alternaterep.WTPartAlternateRep")) {
localQuerySpec.appendAnd();
localQuerySpec.appendWhere(
new SearchCondition(localQuerySpec.getPrimaryClass(),
"oneOffVersionInfo.identifier.oneOffVersionId",
true), new int[] { 0 });
}
try {
localQuerySpec = appendSearchCriteria(localQuerySpec,
this.getLifeCycleStates());
if (ViewManageable.class.isAssignableFrom(localQuerySpec
.getPrimaryClass())) {
localQuerySpec.appendAnd();
localQuerySpec = ViewConfigSpec.newViewConfigSpec(getView(),
getVariation1(), getVariation2()).appendSearchCriteria(
localQuerySpec);
} else {
this.isPrimaryClassViewManageable = false;
}
} catch (WTPropertyVetoException localWTPropertyVetoException) {
throw new WTException(localWTPropertyVetoException);
}
return localQuerySpec;
}
public QueryResult process(QueryResult paramQueryResult) throws WTException {
if ((paramQueryResult == null) || (!paramQueryResult.hasMoreElements())) {
return paramQueryResult;
}
ObjectVector objectVector = new ObjectVector();
while (paramQueryResult.hasMoreElements()) {
Object localObject = paramQueryResult.nextElement();
if (!(localObject instanceof Iterated)) {
Object[] arrayOfObject = { "results", Iterated.class.getName() };
throw new ConfigException("wt.vc.config.configResource", "1",
arrayOfObject);
}
if ((this.isWorkingIncluded())
|| (!WorkInProgressHelper
.isWorkingCopy((Workable) localObject))) {
objectVector.addElement((Iterated) localObject);
}
}
if (this.isPrimaryClassViewManageable) {
ViewConfigSpec viewConfigSpec = null;
try {
viewConfigSpec = ViewConfigSpec.newViewConfigSpec(getView(),
getVariation1(), getVariation2());
} catch (WTPropertyVetoException localWTPropertyVetoException) {
throw new WTException(localWTPropertyVetoException);
}
return new LatestConfigSpec().process(viewConfigSpec
.process(new QueryResult(objectVector)));
}
return new LatestConfigSpec().process(new QueryResult(objectVector));
}
public RelationalConfigSpec getRelationalConfigSpec() throws WTException {
return new RelationalConfigSpec() {
private static final long serialVersionUID = 1L;
public OrderBy[] getOrder(QuerySpec paramAnonymousQuerySpec)
throws WTException {
OrderBy[] orderByArray = new RelationalConfigSpecBridge(
WTPartMultiStateConfigSpec.this)
.getOrder(paramAnonymousQuerySpec);
int i = (WTPartMultiStateConfigSpec.this.variation1 != null ? 1
: 0)
+ (WTPartMultiStateConfigSpec.this.variation2 != null ? 1
: 0);
OrderBy[] orderByArray2 = new OrderBy[orderByArray.length + i];
int j = 0;
for (int k = 0; k < orderByArray.length; k++) {
orderByArray2[(j++)] = orderByArray[k];
if (k == 0) {
if (WTPartMultiStateConfigSpec.this.variation1 != null)
orderByArray2[(j++)] = new ViewManageableOrderByVariation1Primitive(
WTPartMultiStateConfigSpec.this.variation1)
.getOrderBy(true);
if (WTPartMultiStateConfigSpec.this.variation2 != null) {
orderByArray2[(j++)] = new ViewManageableOrderByVariation2Primitive(
WTPartMultiStateConfigSpec.this.variation2)
.getOrderBy(true);
}
}
}
return orderByArray2;
}
public QuerySpec append(QuerySpec paramAnonymousQuerySpec1,
int paramAnonymousInt, QuerySpec paramAnonymousQuerySpec2)
throws WTException {
return appendSearchCriteria(paramAnonymousQuerySpec2);
}
public void readExternal(ObjectInput paramAnonymousObjectInput)
throws IOException, ClassNotFoundException {
}
public void writeExternal(ObjectOutput paramAnonymousObjectOutput)
throws IOException {
}
};
}
}
三、调用示例
调用时,状态参数是一个可以接收多状态属性值的多值参数。
WTPartMultiStateConfigSpec spec = WTPartMultiStateConfigSpec.newWTPartMultiStateConfigSpec(View.newView("Design"), State.RELEASED);
WTPartHelper.service.getUsesWTParts(child, spec);