/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
package org.openoffice.xmerge.util.registry;
import java.util.*;
import java.io.*;
/**
* Manages the converter plug-ins that are currently active.
*
*
This class allows plug-ins to be added or removed dynamically.
*
* This class is a singleton (static) class, so that only one manager can
* exist at a time. It is final, so it may not be sub-classed.
*/
public final class ConverterInfoMgr {
private static final ArrayList converterInfoList = new ArrayList();
/**
* Adds a converter plug-in to the registry.
*
* The {@code ConverterInfo} must have a unique DisplayName and must have
* non-null values for DisplayName, ClassImpl, OfficeMime, and DeviceMime.
*
* @param ci A {@code ConverterInfo} object describing a plug-in.
*
* @throws RegistryException If the {@code ConverterInfo} is not valid.
*/
private static void addPlugIn(ConverterInfo ci) throws RegistryException {
// Validate
if (ci.getDisplayName() == null) {
RegistryException re = new RegistryException(
"Converter must have valid name.");
throw re;
}
if (ci.getClassImpl() == null) {
RegistryException re = new RegistryException(
"Converter must have valid class implementation specified.");
throw re;
}
if (ci.getOfficeMime() == null) {
RegistryException re = new RegistryException(
"Converter must have valid office mime specified.");
throw re;
}
if (! ci.getDeviceMime().hasNext()) {
RegistryException re = new RegistryException(
"Converter must have valid device mime specified.");
throw re;
}
// Verify there is no converter with the same Display Name in the
// registry.
for (ConverterInfo converterInfo : converterInfoList) {
if (ci.getDisplayName().equals(converterInfo.getDisplayName())) {
RegistryException re = new RegistryException(
"Converter with specified display name already exists.");
throw re;
}
}
// Since this is adding to a static Vector, make sure this add method
// call is synchronized.
synchronized (converterInfoList) {
converterInfoList.add(ci);
}
}
/**
* Adds a list of converter plug-ins to the registry.
*
* Each {@code ConverterInfo} in the list must have a unique DisplayName
* and must have non-null values for DisplayName, ClassImpl, OfficeMime, and
* DeviceMime.
*
* @param jarEnum An {@code Enumeration} of {@code ConverterInfo} objects
* describing one or more plug-in(s).
*
* @throws RegistryException If a {@code ConverterInfo} in the
* {@code Vector} is not valid.
*/
public static void addPlugIn(Iterator jarEnum)
throws RegistryException {
while (jarEnum.hasNext()) {
ConverterInfo converterInfo = jarEnum.next();
addPlugIn(converterInfo);
}
}
/**
* Returns an {@code Enumeration} of registered {@code ConverterInfo} objects.
*
* @return An {@code Enumeration} containing the currently registered
* {@code ConverterInfo} objects, an empty {@code Vector} if none
* exist.
*/
private static Iterator getConverterInfoEnumeration() {
return converterInfoList.iterator();
}
/**
* Removes any {@code ConverterInfo} object from the registry that have the
* specified jar name value.
*
* @param jar The name of the jarfile.
*
* @return {@code true} if a {@code ConverterInfo} object was removed,
* {@code false} otherwise.
*/
public static boolean removeByJar(String jar) {
boolean rc = false;
for (Iterator it = converterInfoList.iterator(); it.hasNext();) {
ConverterInfo converterInfo = it.next();
if (jar.equals(converterInfo.getJarName())) {
it.remove();
rc = true;
}
}
return rc;
}
/**
* Removes any {@code ConverterInfo} object from the registry that have the
* specified display name value.
*
* @param name The display name.
*
* @return {@code true} if a {@code ConverterInfo} object was removed,
* {@code false} otherwise.
*/
private static boolean removeByName(String name) {
boolean rc = false;
for (Iterator it = converterInfoList.iterator(); it.hasNext();) {
ConverterInfo converterInfo = it.next();
if (name.equals(converterInfo.getDisplayName())) {
it.remove();
rc = true;
}
}
return rc;
}
/**
* Returns the {@code ConverterInfo} object that supports the specified
* device/office mime type conversion.
*
* If there are multiple {@code ConverterInfo} objects registered that
* support this conversion, only the first is returned.
*
* @param deviceMime The device mime.
* @param officeMime The office mime.
*
* @return The first plug-in that supports the specified conversion.
*/
public static ConverterInfo findConverterInfo(String deviceMime, String officeMime) {
if (deviceMime == null ||
!ConverterInfo.isValidOfficeType(officeMime)) {
return null;
}
// Loop over elements comparing with deviceFromMime
for (ConverterInfo converterInfo : converterInfoList) {
String toDeviceInfo = converterInfo.getOfficeMime();
Iterator fromEnum = converterInfo.getDeviceMime();
// Loop over the deviceMime types.
while (fromEnum.hasNext()) {
String fromDeviceInfo = fromEnum.next();
if (deviceMime.trim().equals(fromDeviceInfo) &&
officeMime.trim().equals(toDeviceInfo)) {
return converterInfo;
}
}
}
return null;
}
/**
* Returns an array of two {@code ConverterInfo} objects that can be chained
* to perform the specified mime type conversion.
*
* If there are multiple {@code ConverterInfo} objects that support this
* conversion, only the first is returned.
*
* @param deviceFromMime The device from mime.
* @param deviceToMime The device to mime.
*
* @return An array of two {@code ConverterInfo} objects that can be chained
* to perform the specified conversion.
*/
private static ConverterInfo[] findConverterInfoChain(String deviceFromMime, String deviceToMime) {
if (deviceFromMime == null || deviceToMime == null) {
return null;
}
ConverterInfo[] converterInfo = new ConverterInfo[2];
// Loop over elements comparing with deviceFromMime
Iterator cifEnum = converterInfoList.iterator();
while (cifEnum.hasNext()) {
converterInfo[0] = cifEnum.next();
String fromOfficeInfo = converterInfo[0].getOfficeMime();
Iterator fromEnum = converterInfo[0].getDeviceMime();
// Loop over the deviceMime types looking for a deviceFromMime
// match.
while (fromEnum.hasNext()) {
String fromDeviceInfo = fromEnum.next();
if (deviceFromMime.trim().equals(fromDeviceInfo)) {
// Found a match for deviceFrom. Now loop over the
// elements comparing with deviceToMime
Iterator citEnum = converterInfoList.iterator();
while (citEnum.hasNext()) {
converterInfo[1] = citEnum.next();
String toOfficeInfo = converterInfo[1].getOfficeMime();
Iterator toEnum = converterInfo[1].getDeviceMime();
// Loop over deviceMime types looking for a
// deviceToMime match.
while (toEnum.hasNext()) {
String toDeviceInfo = toEnum.next();
if (deviceToMime.trim().equals(toDeviceInfo) &&
fromOfficeInfo.equals(toOfficeInfo)) {
// Found a match
return converterInfo;
}
}
}
}
}
}
return null;
}
/**
* Main to let the user specify what plug-ins to register from jarfiles and
* to display the currently registered plug-ins.
*
* @param args Not used.
*/
public static void main(String args[]) {
ConverterInfoReader cir = null;
boolean validate = false;
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
char c = ' ';
boolean exitFlag = false;
while (!exitFlag) {
System.out.println("\nMenu:");
System.out.println("(L)oad plug-ins from a jar file");
System.out.println("(D)isplay name unload");
System.out.println("(J)ar name unload");
System.out.println("(F)ind ConverterInfo");
System.out.println("(C)ind ConverterInfo chain");
System.out.println("(V)iew plug-ins");
System.out.println("(T)oggle Validation");
System.out.println("(Q)uit\n");
try {
c = br.readLine().toUpperCase().trim().charAt(0);
} catch(Exception e) {
System.out.println("Invalid entry");
System.out.println("Error msg: " + e.getMessage());
continue;
}
System.out.println("");
// Quit
if (c == 'Q') {
exitFlag = true;
// Load by Jarfile
} else if (c == 'L') {
System.out.println("Enter path to jarfile: ");
try {
String jarname = br.readLine().trim();
cir = new ConverterInfoReader(jarname,validate);
} catch (RegistryException e) {
System.out.println("Cannot load plug-in ConverterFactory implementation.");
System.out.println("Error msg: " + e.getMessage());
} catch (Exception e) {
System.out.println("Error adding data to registry");
System.out.println("Error msg: " + e.getMessage());
}
if (cir != null) {
Iterator jarInfoEnum = cir.getConverterInfoEnumeration();
try {
ConverterInfoMgr.addPlugIn(jarInfoEnum);
} catch (Exception e) {
System.out.println("Error adding data to registry");
System.out.println("Error msg: " + e.getMessage());
}
}
// Unload by Display Name or Jarfile
} else if (c == 'T') {
if (validate){
System.out.println("Validation switched off");
validate=false;
} else {
System.out.println("Validation switched on");
validate=true;
}
} else if (c == 'D' || c == 'J') {
if (c == 'D') {
System.out.println("Enter display name: ");
} else {
System.out.println("Enter path to jarfile: ");
}
try {
String name = br.readLine().trim();
boolean rc = false;
if (c == 'D') {
rc = ConverterInfoMgr.removeByName(name);
} else {
rc = ConverterInfoMgr.removeByJar(name);
}
if (rc) {
System.out.println("Remove successful.");
} else {
System.out.println("Remove failed.");
}
} catch (Exception e) {
System.out.println("Error removing value from registry");
System.out.println("Error msg: " + e.getMessage());
}
// Find Office Mime
} else if (c == 'F' || c == 'C') {
String findMimeOne = null;
String findMimeTwo = null;
if (c == 'F') {
System.out.println("Enter device mime: ");
} else {
System.out.println("Enter device from mime: ");
}
try {
findMimeOne = br.readLine().trim();
} catch (Exception e) {
System.out.println("Error adding data to registry");
System.out.println("Error msg: " + e.getMessage());
}
if (c == 'F') {
System.out.println("Enter office mime: ");
} else {
System.out.println("Enter device to mime: ");
}
try {
findMimeTwo = br.readLine().trim();
} catch (Exception e) {
System.out.println("Error adding data to registry");
System.out.println("Error msg: " + e.getMessage());
}
if (c == 'F') {
ConverterInfo foundInfo = ConverterInfoMgr.findConverterInfo(findMimeOne, findMimeTwo);
if (foundInfo != null) {
System.out.println(" Found ConverterInfo");
System.out.println(" DisplayName : " + foundInfo.getDisplayName());
} else {
System.out.println(" Did not find ConverterInfo");
}
} else {
ConverterInfo[] foundInfo = ConverterInfoMgr.findConverterInfoChain(findMimeOne,
findMimeTwo);
if (foundInfo != null && foundInfo[0] != null && foundInfo[1] != null ) {
System.out.println(" Found ConverterInfo Chain");
System.out.println(" DisplayName : " + foundInfo[0].getDisplayName());
System.out.println(" DisplayName : " + foundInfo[1].getDisplayName());
} else {
System.out.println(" Did not find ConverterInfo");
}
}
// View
} else if (c == 'V') {
Iterator ciEnum = ConverterInfoMgr.getConverterInfoEnumeration();
int ciCnt = 0;
while (ciEnum.hasNext())
{
System.out.println("");
System.out.println(" Displaying converter number " + ciCnt);
ConverterInfo converterInfo = ciEnum.next();
System.out.println(" DisplayName : " + converterInfo.getDisplayName());
System.out.println(" JarFile : " + converterInfo.getJarName());
System.out.println(" Description : " + converterInfo.getDescription());
System.out.println(" Version : " + converterInfo.getVersion());
System.out.println(" OfficeMime : " + converterInfo.getOfficeMime());
Iterator fromEnum = converterInfo.getDeviceMime();
int feCnt = 1;
while (fromEnum.hasNext())
{
System.out.println(" DeviceMime : (#" + feCnt + ") : " +
fromEnum.next());
feCnt++;
}
if (feCnt == 1) {
System.out.println(" DeviceMime : None specified");
}
System.out.println(" Vendor : " + converterInfo.getVendor());
System.out.println(" ClassImpl : " + converterInfo.getClassImpl());
System.out.println(" XsltSerial : " + converterInfo.getXsltSerial());
System.out.println(" XsltDeserial : " + converterInfo.getXsltDeserial());
System.out.println(" Serialize : " + converterInfo.canSerialize());
System.out.println(" Deserialize : " + converterInfo.canDeserialize());
System.out.println(" Merge : " + converterInfo.canMerge());
ciCnt++;
}
if (ciCnt == 0) {
System.out.println("No converters registered");
}
} else {
System.out.println("Invalid input");
}
}
}
}