// Copyright 2006 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.collect.ImmutableMap; import com.google.enterprise.connector.instantiator.Configuration; import com.google.enterprise.connector.scheduler.Schedule; import com.google.enterprise.connector.servlet.ServletUtil; import com.google.enterprise.connector.spi.XmlUtils; import com.google.enterprise.connector.util.XmlParseUtil; import org.w3c.dom.Element; import java.io.IOException; import java.io.PrintWriter; import java.util.Map; import java.util.TreeMap; /** * An encapsulation of all the information we export/import per connector * instance. */ public class ImportExportConnector { private String name; private Configuration configuration; private Schedule schedule; private String checkpoint; private String typeVersion; public ImportExportConnector() { } /** * @param name the connector's name * @param configuration the connector's Configuration * @param schedule the connector's Schedule * @param checkpoint the connector's Traversal checkpoint string. */ public ImportExportConnector(String name, Configuration configuration, Schedule schedule, String checkpoint) { this(name, configuration, null, schedule, checkpoint); } /** * @param name the connector's name * @param configuration the connector's Configuration * @param typeVersion ConnectorType version string * @param schedule the connector's Schedule * @param checkpoint the connector's Traversal checkpoint string. */ public ImportExportConnector(String name, Configuration configuration, String typeVersion, Schedule schedule, String checkpoint) { setName(name); setConfiguration(configuration); setTypeVersion(typeVersion); setSchedule(schedule); setCheckpoint(checkpoint); } /** * Sets the Connector's name. * * @param name the connector's name */ public void setName(String name) { this.name = name; } /** * Sets the Connector's {@link Configuration}. * * @param configuration the connector's Configuration */ public void setConfiguration(Configuration configuration) { this.configuration = configuration; } /** * Sets the Connector's {@link Schedule}. * * @param schedule the connector's Schedule. */ public void setSchedule(Schedule schedule) { this.schedule = schedule; } /** * Sets the Connector's checkpoint. * * @param checkpoint the connector's checkpoint */ public void setCheckpoint(String checkpoint) { this.checkpoint = checkpoint; } /** * Set the version string for the ConnectorType. * * @param version the version string for the Connector type. */ public void setTypeVersion(String version) { this.typeVersion = version; } /** * @return the Connector's name. */ public String getName() { return name; } /** * @return the Connector's ConnectorType-specific Configuration. */ public Configuration getConfiguration() { return configuration; } /** * @return the connector's ConnectorType's name */ public String getTypeName() { return configuration.getTypeName(); } /** * @return the connector's ConnectorType-specific configuration map. */ public Map<String, String> getConfigMap() { return configuration.getMap(); } /** * @return the connector's ConnectorType-specific configuration XML, * or null if none is available. */ public String getConfigXml() { return configuration.getXml(); } /** * @return the Connector's traversal Schedule, or null if * the Connector has no Schedule. * @see com.google.enterprise.connector.scheduler.Schedule */ public Schedule getSchedule() { return schedule; } /** * @return the connector's traversal schedule as a String, or null if * the connector has no schedule. * @see com.google.enterprise.connector.scheduler.Schedule */ public String getScheduleString() { return (schedule == null) ? "" : schedule.toString(); } /** * @return the connector's traversal checkpoint as a string, or null if * the connector has no checkpoint. */ public String getCheckpoint() { return checkpoint; } /** * @return the connector's version string, or null if * the connector has no version string. */ public String getTypeVersion() { return typeVersion; } /** * Deserializes an ImportExportConnector from XML. * * @param connectorElement an ConnectorInstance XML Element. */ public void fromXml(Element connectorElement) { setName(XmlParseUtil.getFirstElementByTagName( connectorElement, ServletUtil.XMLTAG_CONNECTOR_NAME)); // Extract the Configuration setConfiguration(readConfiguration(connectorElement)); // Extract the Schedule. setSchedule(readSchedule(connectorElement)); // Extract the Traversal Checkpoint. setCheckpoint(readCheckpoint(connectorElement)); } /** * Extract the Traversal Checkpoint from the connectorElement. * * @param connectorElement an ConnectorInstance XML Element. * @return checkpoint as a String, or null if no checkpoint is encoded. */ String readCheckpoint(Element connectorElement) { return XmlParseUtil.getFirstElementByTagName( connectorElement, ServletUtil.XMLTAG_CONNECTOR_CHECKPOINT); } /** * Extract the Traversal Schedule from the connectorElement. * * @param connectorElement an ConnectorInstance XML Element. * @return a Schedule or null if no Schedule is encoded. */ Schedule readSchedule(Element connectorElement) { String scheduleString = XmlParseUtil.getFirstElementByTagName( connectorElement, ServletUtil.XMLTAG_CONNECTOR_SCHEDULES); if (scheduleString != null && scheduleString.trim().length() > 0) { return new Schedule(scheduleString); } else { // Try looking for an exploded Schedule. Element scheduleElement = (Element) connectorElement.getElementsByTagName( ServletUtil.XMLTAG_CONNECTOR_SCHEDULES).item(0); if (scheduleElement != null && scheduleElement.hasChildNodes()) { boolean disabled = Boolean.parseBoolean(XmlParseUtil.getFirstElementByTagName( scheduleElement, ServletUtil.XMLTAG_DISABLED)); int load = Integer.parseInt(XmlParseUtil.getFirstElementByTagName( scheduleElement, ServletUtil.XMLTAG_LOAD)); String delay = XmlParseUtil.getFirstElementByTagName( scheduleElement, ServletUtil.XMLTAG_DELAY); int retryDelayMillis = (delay != null) ? Integer.parseInt(delay) : Schedule.defaultRetryDelayMillis(); String timeIntervals = XmlParseUtil.getFirstElementByTagName( scheduleElement, ServletUtil.XMLTAG_TIME_INTERVALS); return new Schedule(name, disabled, load, retryDelayMillis, timeIntervals); } } return null; } /** * Extract the Connector Configuration from the connectorElement. * * @param connectorElement an ConnectorInstance XML Element. * @return a Configuration */ Configuration readConfiguration(Element connectorElement) { String type = XmlParseUtil.getFirstElementByTagName( connectorElement, ServletUtil.XMLTAG_CONNECTOR_TYPE); if (type == null || type.length() == 0) { Element typeElement = (Element) connectorElement.getElementsByTagName( ServletUtil.XMLTAG_CONNECTOR_TYPE).item(0); type = typeElement.getAttribute("name"); typeVersion = typeElement.getAttribute("version"); } Element configElement = (Element) connectorElement.getElementsByTagName( ServletUtil.XMLTAG_CONNECTOR_CONFIG).item(0); Map<String, String> configMap = XmlParseUtil.getAllAttributes( configElement, ServletUtil.XMLTAG_PARAMETERS); // TODO: Extract encryption status and preserve it. String configXml = null; configElement = (Element) connectorElement.getElementsByTagName( ServletUtil.XMLTAG_CONNECTOR_CONFIG_XML).item(0); if (configElement != null) { configXml = XmlParseUtil.getCdata(configElement); if (configXml != null) { configXml = ServletUtil.restoreEndMarkers(configXml); } } return new Configuration(type, configMap, configXml); } /** * Serializes this connector to XML. * * @param out PrintWriter to write XML output. * @param indent starting indent for the XML tags. */ public void toXml(PrintWriter out, int indent) { ServletUtil.writeXMLTag(out, indent, ServletUtil.XMLTAG_CONNECTOR_INSTANCE, false); ServletUtil.writeXMLElement(out, indent + 1, ServletUtil.XMLTAG_CONNECTOR_NAME, getName()); // Write out the Checkpoint. writeCheckpoint(out, indent + 1); // Write out the Connector Schedule. writeSchedule(out, indent + 1); // Write out the Configuration. writeConfiguration(out, indent + 1); ServletUtil.writeXMLTag(out, indent, ServletUtil.XMLTAG_CONNECTOR_INSTANCE, true); } /** * Write out the Checkpoint to the XML stream. * * @param out PrintWriter to write XML output. * @param indent indent for the XML tag. */ void writeCheckpoint(PrintWriter out, int indent) { if (getCheckpoint() != null) { ServletUtil.writeXMLElement(out, indent, ServletUtil.XMLTAG_CONNECTOR_CHECKPOINT, getCheckpoint()); } } /** * Write out the Schedule to the XML stream. * * @param out PrintWriter to write XML output. * @param indent indent for the XML tag. */ void writeSchedule(PrintWriter out, int indent) { Schedule schedule = getSchedule(); if (schedule != null) { ServletUtil.writeXMLTagWithAttrs(out, indent, ServletUtil.XMLTAG_CONNECTOR_SCHEDULES, ImmutableMap.of( ServletUtil.ATTRIBUTE_VERSION, Schedule.CURRENT_VERSION), false); if (schedule.isDisabled()) { ServletUtil.writeXMLElement(out, indent + 1, ServletUtil.XMLTAG_DISABLED, "true"); } ServletUtil.writeXMLElement(out, indent + 1, ServletUtil.XMLTAG_LOAD, Integer.toString(schedule.getLoad())); ServletUtil.writeXMLElement(out, indent + 1, ServletUtil.XMLTAG_DELAY, Integer.toString(schedule.getRetryDelayMillis())); ServletUtil.writeXMLElement(out, indent + 1, ServletUtil.XMLTAG_TIME_INTERVALS, schedule.getTimeIntervals()); ServletUtil.writeXMLTag(out, indent, ServletUtil.XMLTAG_CONNECTOR_SCHEDULES, true); } } /** * Write out the Configuration to the XML stream. * * @param out PrintWriter to write XML output. * @param indent indent for the XML tag. */ void writeConfiguration(PrintWriter out, int indent) { writeType(out, indent); ServletUtil.writeXMLTag(out, indent, ServletUtil.XMLTAG_CONNECTOR_CONFIG, false); /* TODO: if (flags.contains(Style.LOCAL_ENCRYPTION)) { ServletUtil.writeXMLTagWithAttrs(out, indent, ServletUtil.XMLTAG_CONNECTOR_CONFIG, ImmutableMap.of(ServletUtil.ATTRIBUTE_CRYPT, "internal"), false); } else if (flags.contains(Style.EXTERNAL_ENCRYPTION)) { ServletUtil.writeXMLTagWithAttrs(out, indent, ServletUtil.XMLTAG_CONNECTOR_CONFIG, ImmutableMap.of(ServletUtil.ATTRIBUTE_CRYPT, "external"), false); } else { // TODO: Should this really be the default? // No encryption in legacy tag. ServletUtil.writeXMLTag( out, indent + 2, ServletUtil.XMLTAG_CONNECTOR_CONFIG, false); } */ // TODO: Move this to a utility. Map<String, String> configMap = getConfigMap(); Map<String, String> sorted = new TreeMap<String, String>(configMap); for (Map.Entry<String, String> me : sorted.entrySet()) { ServletUtil.writeXMLTagWithAttrs(out, indent + 1, ServletUtil.XMLTAG_PARAMETERS, ImmutableMap.of( ServletUtil.ATTRIBUTE_NAME, me.getKey(), ServletUtil.ATTRIBUTE_VALUE, me.getValue()), true); } ServletUtil.writeXMLTag(out, indent, ServletUtil.XMLTAG_CONNECTOR_CONFIG, true); // Write out connectorInstance.xml. if (getConfigXml() != null) { ServletUtil.writeXMLTag(out, indent, ServletUtil.XMLTAG_CONNECTOR_CONFIG_XML, false); out.print(ServletUtil.XML_CDATA_START); out.print(ServletUtil.escapeEndMarkers(getConfigXml())); out.println(ServletUtil.XML_CDATA_END); ServletUtil.writeXMLTag(out, indent, ServletUtil.XMLTAG_CONNECTOR_CONFIG_XML, true); } } /** * Write out the Connector TypeName to the XML stream. * * @param out PrintWriter to write XML output. * @param indent indent for the XML tag. */ void writeType(PrintWriter out, int indent) { String version = getTypeVersion(); if (version == null || version.trim().length() == 0) { ServletUtil.writeXMLElement(out, indent, ServletUtil.XMLTAG_CONNECTOR_TYPE, getTypeName()); } else { ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); builder.put(ServletUtil.ATTRIBUTE_NAME, getTypeName()); if (getTypeVersion() != null) { builder.put(ServletUtil.ATTRIBUTE_VERSION, getTypeVersion()); } ServletUtil.writeXMLTagWithAttrs(out, indent, ServletUtil.XMLTAG_CONNECTOR_TYPE, builder.build(), true); } } }