1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package org.openoffice.xmerge.util.registry; 25 26 import java.util.*; 27 import java.io.*; 28 29 /** 30 * Manages the converter plug-ins that are currently active. 31 * This class allows plug-ins to be added or removed dynamically. 32 * This class is a singleton (static) class, so that only one 33 * manager can exist at a time. It is final, so it may not be 34 * subclassed. 35 * 36 * @author: Brian Cameron 37 */ 38 public final class ConverterInfoMgr { 39 40 private static Vector converterInfoList; 41 42 /** 43 * Constructor 44 */ 45 static { 46 converterInfoList = new Vector(); 47 } 48 49 50 /** 51 * Adds a converter plug-in to the registry. The 52 * <code>ConverterInfo</code> must have a unique DisplayName 53 * and must have non-null values for DisplayName, ClassImpl, 54 * OfficeMime, and DeviceMime. 55 * 56 * @param ci A <code>ConverterInfo</code> object 57 * describing a plug-in. 58 * 59 * @throws RegistryException If the <code>ConverterInfo</code> 60 * is not valid. 61 */ addPlugIn(ConverterInfo ci)62 public static void addPlugIn(ConverterInfo ci) throws RegistryException { 63 64 ConverterInfo converterInfo; 65 66 // Validate 67 // 68 if (ci.getDisplayName() == null) { 69 RegistryException re = new RegistryException( 70 "Converter must have valid name."); 71 throw re; 72 } 73 if (ci.getClassImpl() == null) { 74 RegistryException re = new RegistryException( 75 "Converter must have valid class implementation specified."); 76 throw re; 77 } 78 if (ci.getOfficeMime() == null) { 79 RegistryException re = new RegistryException( 80 "Converter must have valid office mime specified."); 81 throw re; 82 } 83 if (! ci.getDeviceMime().hasMoreElements()) { 84 RegistryException re = new RegistryException( 85 "Converter must have valid device mime specified."); 86 throw re; 87 } 88 89 // Verify there is no converter with the same Display Name in 90 // the registry. 91 // 92 Enumeration ciEnum = converterInfoList.elements(); 93 while (ciEnum.hasMoreElements()) { 94 converterInfo = (ConverterInfo)ciEnum.nextElement(); 95 if (ci.getDisplayName().equals(converterInfo.getDisplayName())) { 96 RegistryException re = new RegistryException( 97 "Converter with specified display name already exists."); 98 throw re; 99 } 100 } 101 102 // Since this is a adding to a static Vector, make sure this 103 // add method call is synchronized. 104 // 105 synchronized (converterInfoList) { 106 converterInfoList.add(ci); 107 } 108 } 109 110 111 /** 112 * Adds an <code>Enumeration</code> of converter plug-ins to the registry. 113 * Each <code>ConverterInfo</code> in the <code>Enumeration</code> must have 114 * a unique DisplayName and must have non-null values for DisplayName, 115 * ClassImpl, OfficeMime, and DeviceMime. 116 * 117 * @param jarEnum An <code>Enumeration</code> of <code>ConverterInfo</code> 118 * objects describing one or more plug-in(s). 119 * 120 * @throws RegistryException If a <code>ConverterInfo</code> in the 121 * <code>Enumeration</code> is not valid. 122 */ addPlugIn(Enumeration jarEnum)123 public static void addPlugIn(Enumeration jarEnum) throws RegistryException { 124 125 while (jarEnum.hasMoreElements()) { 126 ConverterInfo converterInfo = (ConverterInfo)jarEnum.nextElement(); 127 addPlugIn(converterInfo); 128 } 129 } 130 131 132 /** 133 * Returns an <code>Enumeration</code> of registered 134 * <code>ConverterInfo</code> objects. 135 * 136 * @return An <code>Enumeration</code> containing the currently registered 137 * <code>ConverterInfo</code> objects, an empty 138 * <code>Vector</code> if none exist. 139 */ getConverterInfoEnumeration()140 public static Enumeration getConverterInfoEnumeration() { 141 return (converterInfoList.elements()); 142 } 143 144 145 /** 146 * Removes any <code>ConverterInfo</code> object from the registry 147 * that have the specified jar name value. 148 * 149 * @param jar The name of the jarfile. 150 * 151 * @return True if a <code>ConverterInfo</code> object was 152 * removed, false otherwise. 153 */ removeByJar(String jar)154 public static boolean removeByJar(String jar) { 155 156 ConverterInfo converterInfo; 157 boolean rc = false; 158 159 // FIX (HJ): Has to use an iterator, since we are removing items 160 /*Enumeration ciEnum = converterInfoList.elements(); 161 while (ciEnum.hasMoreElements()) 162 { 163 converterInfo = (ConverterInfo)ciEnum.nextElement(); 164 if (jar.equals(converterInfo.getJarName())) { 165 converterInfoList.remove(converterInfo); 166 rc = true; 167 } 168 }*/ 169 170 Iterator ciIter = converterInfoList.iterator(); 171 while (ciIter.hasNext()) 172 { 173 converterInfo = (ConverterInfo)ciIter.next(); 174 if (jar.equals(converterInfo.getJarName())) { 175 ciIter.remove(); 176 rc = true; 177 } 178 } 179 return rc; 180 } 181 182 183 /** 184 * Removes any <code>ConverterInfo</code> object from the registry 185 * that have the specified display name value. 186 * 187 * @param name The display name. 188 * 189 * @return True if a <code>ConverterInfo</code> object was 190 * removed, false otherwise. 191 */ removeByName(String name)192 public static boolean removeByName(String name) { 193 194 ConverterInfo converterInfo; 195 boolean rc = false; 196 197 Enumeration ciEnum = converterInfoList.elements(); 198 while (ciEnum.hasMoreElements()) 199 { 200 converterInfo = (ConverterInfo)ciEnum.nextElement(); 201 if (name.equals(converterInfo.getDisplayName())) { 202 converterInfoList.remove(converterInfo); 203 rc = true; 204 } 205 } 206 return rc; 207 } 208 209 210 /** 211 * Returns the <code>ConverterInfo</code> object that supports 212 * the specified device/office mime type conversion. If there 213 * are multiple <code>ConverterInfo</code> objects registered 214 * that support this conversion, only the first is returned. 215 * 216 * @param deviceMime The device mime. 217 * @param officeMime The office mime. 218 * 219 * @return The first plug-in that supports the specified 220 * conversion. 221 */ findConverterInfo(String deviceMime, String officeMime)222 public static ConverterInfo findConverterInfo(String deviceMime, String officeMime) { 223 224 ConverterInfo converterInfo; 225 226 if (deviceMime == null || 227 ConverterInfo.isValidOfficeType(officeMime) == false) { 228 return null; 229 } 230 231 // Loop over elements comparing with deviceFromMime 232 // 233 Enumeration ciEnum = converterInfoList.elements(); 234 while (ciEnum.hasMoreElements()) { 235 236 converterInfo = (ConverterInfo)ciEnum.nextElement(); 237 String toDeviceInfo = (String)converterInfo.getOfficeMime(); 238 Enumeration fromEnum = converterInfo.getDeviceMime(); 239 240 // Loop over the deviceMime types. 241 // 242 while (fromEnum.hasMoreElements()) { 243 String fromDeviceInfo = (String)fromEnum.nextElement(); 244 if (deviceMime.trim().equals(fromDeviceInfo) && 245 officeMime.trim().equals(toDeviceInfo)) { 246 return (converterInfo); 247 } 248 } 249 } 250 return null; 251 } 252 253 254 /** 255 * Returns an array of two <code>ConverterInfo</code> objects that 256 * can be chained to perform the specified mime type conversion. 257 * If there are multiple <code>ConverterInfo</code> objects that 258 * support this conversion, only the first is returned. 259 * 260 * @param deviceFromMime The device from mime. 261 * @param deviceToMime The device to mime. 262 * 263 * @return An array of two <code>ConverterInfo</code> objects 264 * that can be chained to perform the specified 265 * conversion. 266 */ findConverterInfoChain(String deviceFromMime, String deviceToMime)267 public static ConverterInfo[] findConverterInfoChain(String deviceFromMime, String deviceToMime) { 268 269 if (deviceFromMime == null || deviceToMime == null) { 270 return null; 271 } 272 273 ConverterInfo[] converterInfo = new ConverterInfo[2]; 274 275 // Loop over elements comparing with deviceFromMime 276 // 277 Enumeration cifEnum = converterInfoList.elements(); 278 while (cifEnum.hasMoreElements()) { 279 280 converterInfo[0] = (ConverterInfo)cifEnum.nextElement(); 281 String fromOfficeInfo = converterInfo[0].getOfficeMime(); 282 Enumeration fromEnum = converterInfo[0].getDeviceMime(); 283 284 // Loop over the deviceMime types looking for a deviceFromMime 285 // match. 286 // 287 while (fromEnum.hasMoreElements()) { 288 String fromDeviceInfo = (String)fromEnum.nextElement(); 289 290 if (deviceFromMime.trim().equals(fromDeviceInfo)) { 291 292 // Found a a match for deviceFrom. Now loop over the 293 // elements comparing with deviceToMime 294 // 295 Enumeration citEnum = converterInfoList.elements(); 296 while (citEnum.hasMoreElements()) { 297 298 converterInfo[1] = (ConverterInfo)citEnum.nextElement(); 299 String toOfficeInfo = converterInfo[1].getOfficeMime(); 300 Enumeration toEnum = converterInfo[1].getDeviceMime(); 301 302 // Loop over deviceMime types looking for a 303 // deviceToMime match. 304 // 305 while (toEnum.hasMoreElements()) { 306 String toDeviceInfo = (String)toEnum.nextElement(); 307 if (deviceToMime.trim().equals(toDeviceInfo) && 308 fromOfficeInfo.equals(toOfficeInfo)) { 309 310 // Found a match 311 // 312 return (converterInfo); 313 } 314 } 315 } 316 } 317 } 318 } 319 return null; 320 } 321 322 323 /** 324 * main to let the user specify what plug-ins to register from 325 * jarfiles and to display the currently registered plug-ins. 326 * 327 * @param args Not used. 328 */ main(String args[])329 public static void main(String args[]) { 330 331 ConverterInfoReader cir = null; 332 boolean validate = false; 333 InputStreamReader isr = new InputStreamReader(System.in); 334 BufferedReader br = new BufferedReader(isr); 335 char c = ' '; 336 337 boolean exitFlag = false; 338 while (exitFlag == false) { 339 340 System.out.println("\nMenu:"); 341 System.out.println("(L)oad plug-ins from a jar file"); 342 System.out.println("(D)isplay name unload"); 343 System.out.println("(J)ar name unload"); 344 System.out.println("(F)ind ConverterInfo"); 345 System.out.println("(C)ind ConverterInfo chain"); 346 System.out.println("(V)iew plug-ins"); 347 System.out.println("(T)oggle Validation"); 348 System.out.println("(Q)uit\n"); 349 350 try { 351 c = br.readLine().toUpperCase().trim().charAt(0); 352 } catch(Exception e) { 353 System.out.println("Invalid entry"); 354 System.out.println("Error msg: " + e.getMessage()); 355 continue; 356 } 357 358 System.out.println(""); 359 360 // Quit 361 // 362 if (c == 'Q') { 363 exitFlag = true; 364 365 // Load by Jarfile 366 // 367 } else if (c == 'L') { 368 369 System.out.println("Enter path to jarfile: "); 370 try { 371 String jarname = br.readLine().trim(); 372 cir = new ConverterInfoReader(jarname,validate); 373 } catch (RegistryException e) { 374 System.out.println("Cannot load plug-in ConverterFactory implementation."); 375 System.out.println("Error msg: " + e.getMessage()); 376 } catch (Exception e) { 377 System.out.println("Error adding data to registry"); 378 System.out.println("Error msg: " + e.getMessage()); 379 } 380 381 if (cir != null) { 382 Enumeration jarInfoEnum = cir.getConverterInfoEnumeration(); 383 try { 384 ConverterInfoMgr.addPlugIn(jarInfoEnum); 385 } catch (Exception e) { 386 System.out.println("Error adding data to registry"); 387 System.out.println("Error msg: " + e.getMessage()); 388 } 389 } 390 391 // Unload by Display Name or Jarfile 392 // 393 } else if (c == 'T') { 394 if (validate== true){ 395 System.out.println("Validation switched off"); 396 validate=false; 397 }else{ 398 System.out.println("Validation switched on"); 399 validate=true; 400 } 401 } else if (c == 'D' || c == 'J') { 402 403 if (c == 'D') { 404 System.out.println("Enter display name: "); 405 } else { 406 System.out.println("Enter path to jarfile: "); 407 } 408 409 try 410 { 411 String name = br.readLine().trim(); 412 boolean rc = false; 413 414 if (c == 'D') { 415 rc = ConverterInfoMgr.removeByName(name); 416 } else { 417 rc = ConverterInfoMgr.removeByJar(name); 418 } 419 420 if (rc == true) { 421 System.out.println("Remove successful."); 422 } else { 423 System.out.println("Remove failed."); 424 } 425 426 } catch (Exception e) { 427 System.out.println("Error removing value from registry"); 428 System.out.println("Error msg: " + e.getMessage()); 429 } 430 431 // Find Office Mime 432 // 433 } else if (c == 'F' || c == 'C') { 434 435 String findMimeOne = null; 436 String findMimeTwo = null; 437 438 if (c == 'F') { 439 System.out.println("Enter device mime: "); 440 } else { 441 System.out.println("Enter device from mime: "); 442 } 443 444 try { 445 findMimeOne = br.readLine().trim(); 446 } catch (Exception e) { 447 System.out.println("Error adding data to registry"); 448 System.out.println("Error msg: " + e.getMessage()); 449 } 450 451 if (c == 'F') { 452 System.out.println("Enter office mime: "); 453 } else { 454 System.out.println("Enter device to mime: "); 455 } 456 457 try { 458 findMimeTwo = br.readLine().trim(); 459 } catch (Exception e) { 460 System.out.println("Error adding data to registry"); 461 System.out.println("Error msg: " + e.getMessage()); 462 } 463 464 if (c == 'F') { 465 ConverterInfo foundInfo = ConverterInfoMgr.findConverterInfo(findMimeOne, findMimeTwo); 466 if (foundInfo != null) { 467 System.out.println(" Found ConverterInfo"); 468 System.out.println(" DisplayName : " + foundInfo.getDisplayName()); 469 } else { 470 System.out.println(" Did not find ConverterInfo"); 471 } 472 } else { 473 ConverterInfo[] foundInfo = ConverterInfoMgr.findConverterInfoChain(findMimeOne, 474 findMimeTwo); 475 if (foundInfo[0] != null && foundInfo[1] != null ) { 476 System.out.println(" Found ConverterInfo Chain"); 477 System.out.println(" DisplayName : " + foundInfo[0].getDisplayName()); 478 System.out.println(" DisplayName : " + foundInfo[1].getDisplayName()); 479 } else { 480 System.out.println(" Did not find ConverterInfo"); 481 } 482 } 483 484 // View 485 // 486 } else if (c == 'V') { 487 488 Enumeration ciEnum = ConverterInfoMgr.getConverterInfoEnumeration(); 489 490 int ciCnt = 0; 491 while (ciEnum.hasMoreElements()) 492 { 493 System.out.println(""); 494 System.out.println(" Displaying converter number " + ciCnt); 495 ConverterInfo converterInfo = (ConverterInfo)ciEnum.nextElement(); 496 System.out.println(" DisplayName : " + converterInfo.getDisplayName()); 497 System.out.println(" JarFile : " + converterInfo.getJarName()); 498 System.out.println(" Description : " + converterInfo.getDescription()); 499 System.out.println(" Version : " + converterInfo.getVersion()); 500 System.out.println(" OfficeMime : " + converterInfo.getOfficeMime()); 501 Enumeration fromEnum = converterInfo.getDeviceMime(); 502 int feCnt = 1; 503 while (fromEnum.hasMoreElements()) 504 { 505 System.out.println(" DeviceMime : (#" + feCnt + ") : " + 506 (String)fromEnum.nextElement()); 507 feCnt++; 508 } 509 if (feCnt == 1) { 510 System.out.println(" DeviceMime : None specified"); 511 } 512 513 System.out.println(" Vendor : " + converterInfo.getVendor()); 514 System.out.println(" ClassImpl : " + converterInfo.getClassImpl()); 515 System.out.println(" XsltSerial : " + converterInfo.getXsltSerial()); 516 System.out.println(" XsltDeserial : " + converterInfo.getXsltDeserial()); 517 System.out.println(" Serialize : " + converterInfo.canSerialize()); 518 System.out.println(" Deserialize : " + converterInfo.canDeserialize()); 519 System.out.println(" Merge : " + converterInfo.canMerge()); 520 ciCnt++; 521 } 522 523 if (ciCnt == 0) { 524 System.out.println("No converters registered"); 525 } 526 } else { 527 System.out.println("Invalid input"); 528 } 529 } 530 } 531 } 532 533