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    
016    package com.ibm.rational.stp.client.samples;
017    
018    import static com.ibm.rational.stp.client.samples.SimpleQuery.g_callback;
019    import static com.ibm.rational.wvcm.stp.cq.CqFieldValue.ValidationStatus.INVALID;
020    import static com.ibm.rational.wvcm.stp.cq.CqProvider.CQ_ONLY_PROVIDER_CLASS;
021    import static com.ibm.rational.wvcm.stp.cq.CqProvider.DELIVER;
022    import static com.ibm.rational.wvcm.stp.cq.CqProvider.HOLD;
023    import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
024    import static javax.swing.JOptionPane.OK_CANCEL_OPTION;
025    import static javax.swing.JOptionPane.OK_OPTION;
026    import static javax.swing.JOptionPane.showConfirmDialog;
027    import static javax.swing.JOptionPane.showInputDialog;
028    import static javax.swing.JOptionPane.showMessageDialog;
029    
030    import java.util.Arrays;
031    import java.util.List;
032    
033    import javax.wvcm.Location;
034    import javax.wvcm.ProviderFactory;
035    import javax.wvcm.WvcmException;
036    import javax.wvcm.PropertyRequestItem.PropertyRequest;
037    
038    import com.ibm.rational.wvcm.stp.StpLocation.Namespace;
039    import com.ibm.rational.wvcm.stp.cq.CqAction;
040    import com.ibm.rational.wvcm.stp.cq.CqContextResource;
041    import com.ibm.rational.wvcm.stp.cq.CqFieldDefinition;
042    import com.ibm.rational.wvcm.stp.cq.CqFieldValue;
043    import com.ibm.rational.wvcm.stp.cq.CqProvider;
044    import 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     */
050    public 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     */
059    public 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    
076    public 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        
181    static 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    }