001/*
002 * file SimpleEdit.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.SimpleEdit
010 *
011 * (C) 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
016package com.ibm.rational.stp.client.samples;
017
018import static com.ibm.rational.stp.client.samples.SimpleQuery.g_callback;
019import static com.ibm.rational.wvcm.stp.cq.CqFieldValue.ValidationStatus.INVALID;
020import static com.ibm.rational.wvcm.stp.cq.CqProvider.CQ_ONLY_PROVIDER_CLASS;
021import static com.ibm.rational.wvcm.stp.cq.CqProvider.DELIVER;
022import static com.ibm.rational.wvcm.stp.cq.CqProvider.HOLD;
023import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
024import static javax.swing.JOptionPane.OK_CANCEL_OPTION;
025import static javax.swing.JOptionPane.OK_OPTION;
026import static javax.swing.JOptionPane.showConfirmDialog;
027import static javax.swing.JOptionPane.showInputDialog;
028import static javax.swing.JOptionPane.showMessageDialog;
029
030import java.util.Arrays;
031import java.util.List;
032
033import javax.wvcm.Location;
034import javax.wvcm.ProviderFactory;
035import javax.wvcm.WvcmException;
036import javax.wvcm.PropertyRequestItem.PropertyRequest;
037
038import com.ibm.rational.wvcm.stp.StpLocation.Namespace;
039import com.ibm.rational.wvcm.stp.cq.CqAction;
040import com.ibm.rational.wvcm.stp.cq.CqContextResource;
041import com.ibm.rational.wvcm.stp.cq.CqFieldDefinition;
042import com.ibm.rational.wvcm.stp.cq.CqFieldValue;
043import com.ibm.rational.wvcm.stp.cq.CqProvider;
044import com.ibm.rational.wvcm.stp.cq.CqRecord;
045
046/**
047 * Sample CM API Application that allows a ClearQuest record to be edited
048 * interactively.
049 */
050public class SimpleEdit
051{
052    private static final int ERROR = javax.swing.JOptionPane.ERROR_MESSAGE;
053    private static final String SUBTITLE = 
054        "\nEnter field=value;..., or leave blank to finish";
055    
056/**
057 * @param args arg[0] == simple name of edit action; arg[1]=record to edit
058 */
059public static void main(String[] args) throws Exception {
060    while (args.length != 2) {
061        String cmd = showInputDialog("Enter <action> <record>",
062                                     Arrays.deepToString(args));
063        
064        if (cmd == null)
065            return;
066        
067        args = cmd.split("\\s+");
068        
069        if (args.length == 1)
070            showRecord(args[0]);
071    }
072    
073    edit(args);
074}
075
076public static void edit(String[] args) throws Exception {
077    CqProvider provider = (CqProvider) ProviderFactory
078                           .createProvider(CQ_ONLY_PROVIDER_CLASS, g_callback);
079    CqRecord record = provider.buildProxy(CqRecord.class, args[1]);
080    String fields, title = args[0] + " " + record;
081    Location actionLoc = record.stpLocation()
082              .recomposeWithNamespace(Namespace.ACTION).parent().child(args[0]);
083
084    record.setAction(provider.buildProxy(CqAction.class, actionLoc));    
085    
086    while (null != (fields = showInputDialog(null, status(record) + SUBTITLE,
087                                             title, OK_CANCEL_OPTION))) 
088        try {
089            if ((fields = fields.trim()).length() > 0) {
090                for (String set : fields.split(";", -2)) {
091                    String[] nv = set.split("=");
092                    record.setField(nv[0].trim(), nv.length > 1? nv[1]: null);
093                }
094                record = (CqRecord) record.doWriteProperties(ALL_FIELDS, HOLD);
095            } else {
096                record = (CqRecord) record.doDeliver(ALL_FIELDS);
097                showMessageDialog(null, "Success!\n" + status(record),
098                                  title, INFORMATION_MESSAGE);
099                break;
100            }
101        } catch (WvcmException e) {
102            if (OK_OPTION != showConfirmDialog(null, e + "\nContinue?",
103                                               title, OK_CANCEL_OPTION, ERROR))
104                break;
105            record = provider.cqRecord(record.stpLocation());
106        }
107    
108    provider.terminate();
109    System.exit(0);
110}
111
112    static String status(CqRecord record) 
113    throws WvcmException
114    {
115        StringBuffer buf = new StringBuffer();
116        
117        if (!record.hasProperties(ALL_FIELDS))
118            record = (CqRecord)record.doWriteProperties(ALL_FIELDS, HOLD);
119
120        for (CqFieldValue field: record.getAllFieldValues())
121            if (!field.getFieldDefinition().getIsSystemOwned())
122                buf.append((!field.getValueChangedThisAction()? "=== [": 
123                            field.getValidationStatus()==INVALID? "!!!!!!! [": "+++ [") 
124                            + field.getRequiredness().name().charAt(0) + "] "
125                            + field.getName() + " = " + field.getValue() + "\n");
126        
127        return buf.toString();
128    }
129    
130    private static final PropertyRequest ALL_FIELDS = 
131            new PropertyRequest(CqRecord.ALL_FIELD_VALUES
132                                    .nest(CqFieldValue.VALUE
133                                          .nest(CqFieldValue.VALUE, 
134                                                CqFieldValue.VALUE_CHANGED_THIS_ACTION,
135                                                CqFieldValue.VALIDATION_STATUS,
136                                                CqFieldValue.REQUIREDNESS,
137                                                CqFieldValue.FIELD_DEFINITION
138                                                    .nest(CqFieldDefinition
139                                                          .IS_SYSTEM_OWNED))));
140
141    // Similar to edit method, but allows a trailing ';' to signal end of update
142    // so last batch of record updates are written with delivery
143    public static void edit2(String[] args) throws Exception {
144    CqProvider provider = (CqProvider) ProviderFactory
145                           .createProvider(CQ_ONLY_PROVIDER_CLASS, g_callback);
146    CqRecord record = provider.buildProxy(CqRecord.class, args[1]);
147    String fields, title = args[0] + " " + record;
148    Location actionLoc = record.stpLocation()
149              .recomposeWithNamespace(Namespace.ACTION).parent().child(args[0]);
150
151    record.setAction(provider.buildProxy(CqAction.class, actionLoc));    
152    
153    while (null != (fields = showInputDialog(null, status(record) + SUBTITLE,
154                                             title, OK_CANCEL_OPTION))) 
155        try {
156            if (!(fields = fields.trim()).equals(""))
157                for (String set : fields.split("\\s*;\\s*")) {
158                    String[] nv = set.split("\\s*=\\s*");
159                    record.setField(nv[0], nv.length > 1? nv[1]: null);
160                }
161            
162            if (!fields.matches("|.*;")) {
163                record = (CqRecord) record.doWriteProperties(ALL_FIELDS, HOLD);    
164            } else {
165                record = (CqRecord) record.doWriteProperties(ALL_FIELDS, DELIVER);
166                showMessageDialog(null, "Success!\n" + status(record),
167                                  title, INFORMATION_MESSAGE);
168                break;
169            }
170        } catch (WvcmException e) {
171            if (OK_OPTION != showConfirmDialog(null, e + "\nContinue?",
172                                               title, OK_CANCEL_OPTION, ERROR))
173                break;
174            record = provider.cqRecord(record.stpLocation());
175        }
176    
177    provider.terminate();
178    System.exit(0);
179}
180    
181static void showRecord(String location) throws Exception {
182    CqProvider provider = (CqProvider) ProviderFactory
183                           .createProvider(CQ_ONLY_PROVIDER_CLASS, g_callback);
184    CqRecord record = provider.buildProxy(CqRecord.class, location);
185    
186    PropertyRequest wantedProperties = new PropertyRequest
187        (CqRecord.LEGAL_ACTIONS.nest(CqAction.DISPLAY_NAME),
188         CqRecord.ALL_FIELD_VALUES
189             .nest(CqFieldValue.VALUE
190                   .nest(CqFieldValue.VALUE,
191                         CqFieldValue.FIELD_DEFINITION
192                             .nest(CqFieldDefinition.IS_SYSTEM_OWNED))));
193    record = (CqRecord)record.doReadProperties(wantedProperties);
194
195    StringBuffer buf = new StringBuffer("Fields...\n");
196    
197    for (CqFieldValue field: record.getAllFieldValues())
198        if (!field.getFieldDefinition().getIsSystemOwned() || field.getName().equals("State"))
199            buf.append("  " + field.getName() + " = " + field.getValue() + "\n");
200    
201    buf.append("\nLegal Actions...\n  ");
202    
203    for (CqAction action: record.getLegalActions())
204        buf.append(action.getDisplayName() + ", ");
205    
206    showMessageDialog(null, buf.toString(), location, INFORMATION_MESSAGE); 
207    provider.terminate();
208}
209}