001 /*
002 * file SimpleCreateQuery.java
003 *
004 * Licensed Materials - Property of IBM
005 * Restricted Materials of IBM - you are allowed to copy, modify and
006 * redistribute this file as part of any program that interfaces with
007 * IBM Rational CM API.
008 *
009 * com.ibm.rational.stp.client.samples.SimpleCreateQuery
010 *
011 * © Copyright IBM Corporation 2004, 2008. All Rights Reserved.
012 * Note to U.S. Government Users Restricted Rights: Use, duplication or
013 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
014 */
015
016 package com.ibm.rational.stp.client.samples;
017
018 import static javax.swing.JOptionPane.showInputDialog;
019
020 import java.util.ArrayList;
021 import java.util.List;
022
023 import javax.swing.JOptionPane;
024 import javax.wvcm.ProviderFactory;
025 import javax.wvcm.WvcmException;
026 import javax.wvcm.PropertyRequestItem.PropertyRequest;
027
028 import com.ibm.rational.wvcm.stp.StpLocation;
029 import com.ibm.rational.wvcm.stp.StpProvider;
030 import com.ibm.rational.wvcm.stp.StpResource;
031 import com.ibm.rational.wvcm.stp.StpProvider.Domain;
032 import com.ibm.rational.wvcm.stp.cc.CcProvider;
033 import com.ibm.rational.wvcm.stp.cq.CqFieldDefinition;
034 import com.ibm.rational.wvcm.stp.cq.CqProvider;
035 import com.ibm.rational.wvcm.stp.cq.CqQuery;
036 import com.ibm.rational.wvcm.stp.cq.CqRecordType;
037 import com.ibm.rational.wvcm.stp.cq.CqResultSet;
038 import com.ibm.rational.wvcm.stp.cq.CqQuery.DisplayField;
039 import com.ibm.rational.wvcm.stp.cq.CqQuery.Filter;
040 import com.ibm.rational.wvcm.stp.cq.CqQuery.Filter.Operation;
041 import com.ibm.rational.wvcm.stp.cq.CqQuery.FilterLeaf.TargetType;
042
043 /**
044 * @author trw
045 *
046 */
047 public class SimpleCreateQuery
048 {
049
050 public static void main(String[] args) throws Exception
051 {
052 g_provider = (CqProvider) ProviderFactory
053 .createProvider(CqProvider.CQ_ONLY_PROVIDER_CLASS, g_callback);
054
055 // Get the location for the new query from the user
056 StpLocation location = g_provider.stpLocation
057 (showInputDialog("Where do you want to create the query?",
058 "cq.query:<query path>@<dbset>/<userdb>"));
059
060 // Get a proxy for the record type the query will target
061 CqRecordType rt = g_provider.buildProxy(CqRecordType.class,
062 "cq.record:Defect@"
063 + location.getRepo());
064
065 // Construct display field array and filter expression for the query
066 DisplayField[] fields =
067 new DisplayField[] {
068 buildColumn(rt, "id"),
069 buildColumn(rt, "headline"),
070 buildColumn(rt, "customer.name"),
071 buildColumn(rt, "project.name"),
072 buildColumn(rt, "description") };
073 Filter filter =
074 g_provider.buildFilterLeaf(buildPath(rt, "Owner.login_name"),
075 Operation.IS_EQUAL,
076 TargetType.CONSTANT,
077 "engineer");
078
079 // Create a permanent version of this query
080 CqQuery query = g_provider.cqQuery(location);
081
082 query.setPrimaryRecordType(rt);
083 query.setDisplayFields(fields);
084 query.setFiltering(filter);
085
086 query.doCreateQuery(null);
087
088 // Execute the query and print the results (optional)
089 CqResultSet results = query.doExecute(1, Integer.MAX_VALUE, null);
090
091 while (results.hasNext()) {
092 String[] row = results.next().getStrings();
093 System.out.println(row[0] + ": (from " + row[2] + ") " + row[1]);
094 }
095
096 results.release();
097
098 // Clean up (present only for a repeatable demonstration)
099 query.doUnbindAll(null);
100 }
101
102 static DisplayField buildColumn(CqRecordType rt,
103 String path) throws WvcmException
104 {
105 return rt.cqProvider().buildDisplayField(buildPath(rt, path), true);
106 }
107
108 static CqFieldDefinition[] buildPath(CqRecordType rt,
109 String path) throws WvcmException
110 {
111 List<CqFieldDefinition> result = new ArrayList<CqFieldDefinition>();
112 if (rt.lookupProperty(CqRecordType.FIELD_DEFINITIONS) instanceof Exception)
113 rt = (CqRecordType) rt.doReadProperties(QUERY_RECORD_TYPE_PROPS);
114 for (String name : path.split("\\.")) {
115 if (rt == null)
116 throw new IllegalArgumentException("Field preceeding " + name
117 + " does not reference a record");
118 CqFieldDefinition def = find(rt, name);
119 result.add(def);
120 rt = null;
121 switch (def.getFieldType()) {
122 case RESOURCE:
123 case RESOURCE_LIST:
124 rt =
125 (CqRecordType) def.getReferencedRecordType()
126 .doReadProperties(QUERY_RECORD_TYPE_PROPS);
127 }
128 }
129 return result.toArray(new CqFieldDefinition[result.size()]);
130 }
131
132 static CqFieldDefinition find(CqRecordType rt,
133 String name) throws WvcmException
134 {
135 for (CqFieldDefinition fieldDef : rt.getFieldDefinitions())
136 if (fieldDef.getDisplayName().compareToIgnoreCase(name) == 0)
137 return fieldDef;
138 throw new IllegalArgumentException("'" + name + "' is not a field ");
139 }
140
141 private static final PropertyRequest FIELD_DEFN_PROPS = new PropertyRequest(StpResource.DISPLAY_NAME, CqFieldDefinition.VALUE_TYPE, CqFieldDefinition.FIELD_TYPE, CqFieldDefinition.REFERENCED_RECORD_TYPE);
142
143 private static final PropertyRequest QUERY_RECORD_TYPE_PROPS = new PropertyRequest(StpResource.DISPLAY_NAME, CqRecordType.FIELD_DEFINITIONS.nest(FIELD_DEFN_PROPS));
144
145 static StpProvider.StpCallback g_callback = new StpProvider.StpCallback()
146 {
147 public Authentication getAuthenticationEx(Domain domain,
148 String realm,
149 int retryCount,
150 StpProvider provider,
151 WvcmException failure) throws WvcmException
152 {
153 if (m_unpw != null && retryCount == 0)
154 return m_unpw;
155 String title = "Enter " + domain + " Username '+' Password for " + realm + " [" + retryCount + "]";
156 if (failure != null)
157 title = "Login failed: " + failure + "\n" + title;
158 String unpw = JOptionPane.showInputDialog(title, "admin+");
159 if (unpw == null || unpw.length() == 0)
160 throw new IllegalAccessError("User canceled request");
161 return m_unpw = unpw.equals("anonymous")? null : new UnPw(unpw);
162 }
163
164 public Authentication getAuthentication(String r,
165 int c)
166 {
167 return null;
168 }
169
170 private UnPw m_unpw;
171 };
172
173 /**
174 * A simple Authentication object in which the username and password
175 * obtained from the user is cached for use by the CM API.
176 */
177 static class UnPw implements CcProvider.CcAuthentication {
178 /**
179 * Constructs an Authentication object
180 *
181 * @param unpw A String containing username+password.
182 */
183 UnPw(String unpw) { m_data = unpw.split("\\+", -2); }
184
185 public String loginName() { return m_data[0]; }
186 public String password() { return m_data.length > 1 ? m_data[1] : ""; };
187 public String getPrimaryGroupName() { return m_data.length > 2 ? m_data[2] : ""; }
188
189 /* (non-Javadoc)
190 * @see com.ibm.rational.wvcm.stp.cc.CcProvider.CcAuthentication#getGroupList()
191 */
192 public List<String> getGroupList()
193 {
194 return null;
195 }
196
197 /** The cached credentials */
198 private String[] m_data;
199
200 }
201
202 static CqProvider g_provider;
203 }