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    }