// 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.test; import com.google.enterprise.connector.instantiator.Configuration; import com.google.enterprise.connector.servlet.ServletUtil; import com.google.enterprise.connector.spi.Principal; import com.google.enterprise.connector.spi.SimpleDocument; import com.google.enterprise.connector.spi.SpiConstants; import com.google.enterprise.connector.spi.Value; import junit.framework.Assert; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Logger; public class ConnectorTestUtils { private static final Logger LOGGER = Logger.getLogger(ConnectorTestUtils.class.getName()); private ConnectorTestUtils() { // prevents instantiation } /** * Removes the connector manager version string from the buffer. * This allows the tests that compare actual output to expected * output to function across versions, jvms, and platforms. */ public static void removeManagerVersion(StringBuffer buffer) { int start = buffer.indexOf(" <" + ServletUtil.XMLTAG_INFO + ">" + ServletUtil.MANAGER_NAME); if (start >= 0) { buffer.delete(start, buffer.indexOf("\n", start) + 1); } } /** * Removes colspan="1" rowspan="1" attributes from processed * XML form snippets. These seem to be added by some Java * DOM engines, but not others. */ public static String removeColRowSpan(String str) { if (str == null) { return null; } else { return str.replaceAll(" colspan=\"1\"", "") .replaceAll(" rowspan=\"1\"", ""); } } /** * Compare two maps. The maps need not be identical, but map1 * should be a subset of map2. Note that this is slightly different * behavior than earlier versions of compareMaps. * * @param map1 a Map that should be a subset of map2 * @param map2 a Map that should be a superset of map1 */ public static <T, U> void compareMaps(Map<T, U> map1, Map<T, U> map2) { Set<T> set1 = map1.keySet(); Set<T> set2 = map2.keySet(); Assert.assertTrue("there is a key in map1 that's not in map2", set2.containsAll(set1)); for (T key : set1) { Assert.assertEquals(map1.get(key), map2.get(key)); } } /** * Compares two Configurations for equality. * * @param expected the expected configuration. * @param config the configuration that should match expected. */ public static void compareConfigurations(Configuration expected, Configuration config) { Assert.assertNotNull(config); Assert.assertEquals(expected.getTypeName(), config.getTypeName()); Assert.assertEquals(expected.getXml(), config.getXml()); compareMaps(expected.getMap(), config.getMap()); } public static boolean mkdirs(File file) { if (file.exists() && file.isDirectory()) { return true; } boolean res = file.mkdirs(); if (!res) { LOGGER.warning("Failed to create directory " + file.getPath()); } return res; } public static boolean deleteAllFiles(File file) { if (!file.exists()) { return true; } if (file.isDirectory()) { for (File f : file.listFiles()) { deleteAllFiles(f); } } boolean res = file.delete(); if (!res) { LOGGER.warning("Failed to delete " + file.getPath()); } return res; } public static void copyFile(String source, String dest) throws IOException { InputStream in = new FileInputStream(new File(source)); OutputStream out = new FileOutputStream(new File(dest)); byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } in.close(); out.close(); } public static void deleteFile(String file) { File f = new File(file); if (f.exists() && !f.delete()) { throw new IllegalStateException("Deletion failed " + file); } } /** * Creates a {@link SimpleDocument} with the provided id and a * minimal set of additional properties. */ public static SimpleDocument createSimpleDocument(String docId) { Map<String, Object> props = createSimpleDocumentBasicProperties(docId); return createSimpleDocument(props); } /** * Creates a {@link Map} with basic properties filled for * constructing a {@link SimpleDocument} */ public static Map<String, Object> createSimpleDocumentBasicProperties( String docId) { Map<String, Object> props = new HashMap<String, Object>(); Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(3600 * 1000); props.put(SpiConstants.PROPNAME_LASTMODIFIED, cal); props.put(SpiConstants.PROPNAME_DOCID, docId); props.put(SpiConstants.PROPNAME_MIMETYPE, "text/plain"); props.put(SpiConstants.PROPNAME_CONTENT, "now is the time"); props.put(SpiConstants.PROPNAME_DISPLAYURL, "http://www.comtesturl.com/test?" + docId); props.put(SpiConstants.PROPNAME_ACLGROUPS, new Principal("Everyone")); return props; } /** * Creates a {@link SimpleDocument} with the properties in the provided * {@link Map}. */ public static SimpleDocument createSimpleDocument(Map<String, ?> props) { return new SimpleDocument(createSpiProperties(props)); } @SuppressWarnings("unchecked") public static void addValueToList(Object obj, List<Value> list) { if (obj instanceof List) { for (Object listItem : (List<Object>) obj) { addValueToList(listItem, list); } } else if (obj instanceof Value) { list.add((Value) obj); } else if (obj instanceof String) { list.add(Value.getStringValue((String) obj)); } else if (obj instanceof Calendar) { list.add(Value.getDateValue((Calendar) obj)); } else if (obj instanceof InputStream) { list.add(Value.getBinaryValue((InputStream) obj)); } else if (obj instanceof Boolean) { list.add(Value.getBooleanValue((Boolean) obj)); } else if (obj instanceof Long) { list.add(Value.getLongValue((Long) obj)); } else if (obj instanceof Double) { list.add(Value.getDoubleValue((Double) obj)); } else if (obj instanceof Principal) { list.add(Value.getPrincipalValue((Principal) obj)); } else { throw new AssertionError(obj); } } /** * Creates a properties map matching the SPI type, mapping String * property names to {@code List<Value>}. */ public static Map<String, List<Value>> createSpiProperties( Map<String, ?> props) { Map<String, List<Value>> spiValues = new HashMap<String, List<Value>>(); for (Map.Entry<String, ?> entry : props.entrySet()) { Object obj = entry.getValue(); List<Value> values = new ArrayList<Value>(); addValueToList(obj, values); spiValues.put(entry.getKey(), values); } return spiValues; } }