001 /* 002 * file Utilities.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.Utilities 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 java.awt.Component; 019 import java.io.File; 020 import java.io.FileReader; 021 import java.lang.reflect.InvocationTargetException; 022 import java.util.List; 023 024 import javax.swing.JOptionPane; 025 import javax.wvcm.Feedback; 026 import javax.wvcm.ProviderFactory; 027 import javax.wvcm.Resource; 028 import javax.wvcm.ResourceList; 029 import javax.wvcm.WvcmException; 030 import javax.wvcm.PropertyRequestItem.PropertyRequest; 031 import javax.wvcm.ProviderFactory.Callback; 032 import javax.wvcm.ProviderFactory.Callback.Authentication; 033 034 import com.ibm.rational.wvcm.stp.StpException; 035 import com.ibm.rational.wvcm.stp.StpProvider; 036 import com.ibm.rational.wvcm.stp.StpResource; 037 import com.ibm.rational.wvcm.stp.StpProvider.Domain; 038 import com.ibm.rational.wvcm.stp.StpProvider.StpCallback; 039 import com.ibm.rational.wvcm.stp.cq.CqDbSet; 040 import com.ibm.rational.wvcm.stp.cq.CqProvider; 041 import com.ibm.rational.wvcm.stp.cq.CqUser; 042 import com.ibm.rational.wvcm.stp.cq.CqUserDb; 043 044 /** 045 * A collection of static utility methods supporting the CM API examples 046 */ 047 public class Utilities { 048 049 /** 050 * A simple Authentication object in which the username and password 051 * obtained from the user is cached for use by the CM API. 052 */ 053 static class UnPw implements Authentication { 054 /** 055 * Constructs an Authentication object 056 * 057 * @param unpw A String[] containing the username and password. 058 */ 059 UnPw(String[] unpw) { m_data = unpw; } 060 061 public String loginName() { return m_data[0]; } 062 public String password() { return m_data.length > 1 ? m_data[1] : ""; }; 063 064 /** The cached credentials */ 065 private String[] m_data; 066 } 067 068 /** Password used by static callback */ 069 public static String g_pass = ""; 070 /** User name used by static callback */ 071 public static String g_user = "admin"; 072 073 private static Callback g_callback = new Callback() 074 { 075 public Authentication getAuthentication(String realm, int retryCount) 076 { 077 if (retryCount > 0) 078 throw new IllegalAccessError("Wrong username/password for " + realm); 079 return new Authentication() 080 { 081 public String loginName() 082 { 083 return g_user; 084 } 085 086 public String password() 087 { 088 return g_pass; 089 } 090 }; 091 } 092 }; 093 094 public static CqProvider getStaticProvider() 095 throws Exception 096 { 097 return (CqProvider) ProviderFactory 098 .createProvider(CqProvider.CQ_ONLY_PROVIDER_CLASS, g_callback); 099 } 100 101 /** 102 * Constructs an instance of the CM API provider with or without an 103 * authenticator. 104 * 105 * @return The instantiated Provider object 106 * @throws Exception 107 * If the Provider could not be instantiated 108 */ 109 static StpProvider getProvider() throws Exception { 110 try { 111 Callback callback = new StpCallback() { 112 private UnPw m_unpw; 113 114 public Authentication getAuthentication(String r, int c) 115 { return null; /* Will not be called */ } 116 117 public Authentication getAuthenticationEx(Domain domain, 118 String realm, 119 int retryCount, 120 StpProvider provider, 121 WvcmException failure) 122 throws WvcmException 123 { 124 // Try to reuse last credentials on each new repository 125 if (m_unpw != null && retryCount == 0) 126 return m_unpw; 127 128 String title = "Enter " + domain 129 + " Username '+' Password for " 130 + realm + " [" + retryCount + "]"; 131 132 if (failure != null) 133 title = "Login failed: " + failure + "\n" + title; 134 135 String unpw = JOptionPane.showInputDialog(title, "admin+"); 136 137 if (unpw == null || unpw.length() == 0) 138 throw new IllegalAccessError("User canceled request"); 139 140 if (unpw.equals("anonymous")) 141 return null; 142 143 if (unpw.startsWith("@")) { 144 File file = new File(unpw.substring(1)); 145 146 try { 147 FileReader reader = new FileReader(file); 148 char[] buf = new char[100]; 149 int count = reader.read(buf); 150 151 unpw = new String(buf, 0, count); 152 reader.close(); 153 } catch (Throwable t) { 154 Utilities.exception(null, 155 "Reading password file " + unpw, 156 t); 157 } 158 } 159 160 return m_unpw = new UnPw(unpw.split("\\+", -2)); 161 } 162 }; 163 164 // Instantiate a Provider 165 return (StpProvider) ProviderFactory 166 .createProvider(StpProvider.PROVIDER_CLASS, callback); 167 } catch (InvocationTargetException ite) { 168 WvcmException e = (WvcmException) ite.getTargetException(); 169 170 System.out.println("*** " + e); 171 172 for (Throwable nested: e.getNestedExceptions()) 173 System.out.println("*** " + nested); 174 175 throw e; 176 } 177 } 178 179 static ResourceList<CqUserDb> getUserDbList(CqProvider provider, 180 PropertyRequest feedback) 181 throws WvcmException 182 { 183 PropertyRequest wantedProps = 184 new PropertyRequest(CqDbSet.CURRENT_USER 185 .nest(CqUser.SUBSCRIBED_DATABASES.nest(feedback))); 186 ResourceList<CqUserDb> result = provider.resourceList(); 187 188 for (CqDbSet set : provider.doGetDbSetList(wantedProps)) { 189 if (set.getResourceError() == null) 190 result.addAll(set.getCurrentUser().getSubscribedDatabases()); 191 } 192 193 return result; 194 } 195 196 /** 197 * Extracts the message content from a Throwable and returns it as a 198 * hierarchical array of Strings capturing the nesting of the Throwable's 199 * message components. This structure formats reasonably in a SWING 200 * showMessageDialog invocation. 201 * 202 * @param ex The Throwable object whose message content is to be extracted. 203 * @return If the given Throwable has nested components, an array consisting 204 * of the Throwable's message and an array of the nested messages. 205 */ 206 private static Object messages(Throwable ex) { 207 String msg = ex.getLocalizedMessage(); 208 209 if (msg == null || msg.length() == 0) 210 msg = ex.toString(); 211 212 if (ex instanceof StpException) { 213 Throwable[] nested = ((StpException) ex).getNestedExceptions(); 214 215 if (nested != null && nested.length > 0) { 216 Object[] msgs = new Object[nested.length]; 217 218 for (int i = 0; i < msgs.length; ++i) 219 msgs[i] = messages(nested[i]); 220 221 return new Object[] { msg, msgs }; 222 } 223 } else if (ex.getCause() != null) { 224 return new Object[] {msg, new Object[]{messages(ex.getCause())}}; 225 } 226 227 return msg; 228 } 229 230 /** 231 * Displays a Swing dialog containing the messages associated with a given 232 * Throwable. 233 * 234 * @param frame The parent frame for the message dialog. 235 * @param title The title to appear in the dialog window. 236 * @param ex The throwable whose messages are to be displayed. 237 */ 238 static void exception(Component frame, String title, Throwable ex) { 239 JOptionPane.showMessageDialog(frame, 240 messages(ex), 241 title, 242 JOptionPane.ERROR_MESSAGE); 243 } 244 245 /** 246 * Returns a String suitable for displaying the type of resource as 247 * determined by its proxy class. 248 * 249 * @param resource 250 * A Resource proxy from which the type of resource will be 251 * determined. 252 * @return A String containing the simple name of the most derived CM API 253 * interface implemented by the given proxy. 254 */ 255 static String resourceType(Resource resource) { 256 Class interfaces[] = resource.getClass().getInterfaces(); 257 Class<?> choice = Resource.class; 258 259 for (int i = 0; i < interfaces.length; ++i) { 260 String name = interfaces[i].getName(); 261 if (name.startsWith("com.ibm.rational.wvcm.") 262 || name.startsWith("javax.wvcm")) { 263 264 // Within the CM API, select the most derived interface 265 // this resource implements 266 if (choice.isAssignableFrom(interfaces[i])) 267 choice = interfaces[i]; 268 } 269 } 270 271 String name = choice.getName(); 272 273 return name.substring(1+name.lastIndexOf('.')); 274 } 275 276 static boolean isListOfResources(Object val) 277 { 278 return val instanceof ResourceList; 279 } 280 281 static ResourceList<? extends StpResource> toResourceList(StpProvider provider, 282 List list) 283 { 284 if (list instanceof ResourceList) 285 return (ResourceList<? extends StpResource>)list; 286 287 return provider.resourceList(); 288 } 289 }