// Copyright 2007 Google Inc. // // Licensed 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 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.enterprise.connector.importexport; import com.google.common.annotations.VisibleForTesting; import com.google.enterprise.connector.common.AbstractCommandLineApp; import com.google.enterprise.connector.common.StringUtils; import com.google.enterprise.connector.instantiator.Configuration; import com.google.enterprise.connector.instantiator.Instantiator; import com.google.enterprise.connector.instantiator.InstantiatorException; import com.google.enterprise.connector.manager.Context; import com.google.enterprise.connector.persist.ConnectorExistsException; import com.google.enterprise.connector.persist.ConnectorNotFoundException; import com.google.enterprise.connector.persist.ConnectorTypeNotFoundException; import com.google.enterprise.connector.scheduler.Schedule; import com.google.enterprise.connector.spi.ConfigureResponse; import com.google.enterprise.connector.util.SAXParseErrorHandler; import com.google.enterprise.connector.util.XmlParseUtil; import org.apache.commons.cli.CommandLine; import org.w3c.dom.Document; import org.w3c.dom.Element; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.HashSet; import java.util.Locale; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; /** * Legacy Utility to import/export connectors from/to XML. * Used by the GSA. */ public class ImportExport extends AbstractCommandLineApp { private static final Logger LOGGER = Logger.getLogger(ImportExport.class.getName()); /** * Returns a ImportExportConnectorList representing the current * set of connectors. * * @return a ImportExportConnectorList */ @VisibleForTesting static final ImportExportConnectorList getConnectors() { ImportExportConnectorList connectors = new ImportExportConnectorList(); Instantiator instantiator = Context.getInstance().getInstantiator(); for (String connectorName : instantiator.getConnectorNames()) { try { Configuration configuration = instantiator.getConnectorConfiguration(connectorName); if (configuration != null) { Schedule schedule = instantiator.getConnectorSchedule(connectorName); connectors.add(new LegacyImportExportConnector( connectorName, configuration, schedule, null)); } } catch (ConnectorNotFoundException e) { // This shouldn't happen. LOGGER.warning("Connector " + connectorName + " not found!"); } } return connectors; } /** * Imports a list of connectors. Replaces the existing connectors with the * connectors in {@code connectors}. For each connector in {@code connectors}, * update an existing connector if the connector names match or create a new * connector if it doesn't already exist. * Unless instructed otherwise, remove any existing connectors which are not * included in {@code connectors}. * * @param connectors a {@link ImportExportConnectorList} * @param noRemove {@code setConnectors} removes previous connectors * which are not included in {@code connectors} if and only if * {@code noremove} is {@code false}. */ static final void setConnectors(ImportExportConnectorList connectors, boolean noRemove) { Instantiator instantiator = Context.getInstance().getInstantiator(); Set<String> previousConnectorNames = new HashSet<String>(instantiator.getConnectorNames()); for (ImportExportConnector connector : connectors) { String name = connector.getName(); try { // Store the Configuration. boolean update = previousConnectorNames.contains(name); Configuration configuration = connector.getConfiguration(); ConfigureResponse configureResponse = instantiator.setConnectorConfiguration(name, configuration, Locale.ENGLISH, update); if (configureResponse != null) { LOGGER.warning("setConnectorConfiguration(name=" + name + "\"): " + configureResponse.getMessage()); continue; } // Store the Schedule. instantiator.setConnectorSchedule(name, connector.getSchedule()); previousConnectorNames.remove(name); } catch (ConnectorNotFoundException e) { // This shouldn't happen. LOGGER.warning("Connector " + name + " not found!"); } catch (ConnectorExistsException e) { // This shouldn't happen. LOGGER.warning("Connector " + name + " already exists!"); } catch (ConnectorTypeNotFoundException e) { LOGGER.warning("Connector Type " + connector.getTypeName() + " not found!"); } catch (InstantiatorException e) { LOGGER.log(Level.WARNING, "Failed to create connector " + name + ": ", e); } } // Remove previous connectors which no longer exist. if (!noRemove) { for (String name : previousConnectorNames) { try { instantiator.removeConnector(name); } catch (InstantiatorException e) { LOGGER.log(Level.WARNING, "Failed to remove connector " + name + ": ", e); } } } } /** * Reads a list of connectors from an XML file. * * @param filename source XML file for connectors. * @return an ImportExportConnectorList */ public static ImportExportConnectorList readFromFile(String filename) throws IOException { String xmlString = StringUtils.streamToStringAndThrow(new FileInputStream(filename)); Document document = XmlParseUtil.parse(xmlString, new SAXParseErrorHandler(), XmlParseUtil.nonEntityResolver); Element connectorsElement = document.getDocumentElement(); ImportExportConnectorList connectors = new ImportExportConnectorList(); connectors.fromXml(document.getDocumentElement(), LegacyImportExportConnector.class); return connectors; } /** * Writes a list of connectors to an XML file. * * @param connectors an ImportExportConnectorList * @param filename destination XML file for connectors. */ public static void writeToFile(String filename, ImportExportConnectorList connectors) throws IOException { PrintWriter out = new PrintWriter(new OutputStreamWriter( new FileOutputStream(filename), "UTF-8")); connectors.toXml(out, 0); out.close(); } @Override public String getName() { return "ImportExport"; } @Override public String getDescription() { return "Imports and Exports Connector configurations."; } @Override public String getCommandLineSyntax() { return super.getCommandLineSyntax() + "(export|import|import-no-remove) <filename>"; } @Override public void run(CommandLine commandLine) throws Exception { initStandAloneContext(true); String[] args = commandLine.getArgs(); try { if (args.length == 2 && args[0].equals("export")) { writeToFile(args[1], getConnectors()); } else if (args.length == 2 && args[0].equals("import")) { setConnectors(readFromFile(args[1]), false); } else if (args.length == 2 && args[0].equals("import-no-remove")) { setConnectors(readFromFile(args[1]), true); } else { printUsage(); } } finally { shutdown(); } } /** * A utility to import/export connectors from/to an XML file. * <pre> * usage: ImportExport (export|import|import-no-remove) <filename> * </pre> */ public static final void main(String[] args) throws Exception { ImportExport app = new ImportExport(); app.run(app.parseArgs(args)); System.exit(0); } }