/*
* ====================
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License("CDDL") (the "License"). You may not use this file
* except in compliance with the License.
*
* You can obtain a copy of the License at
* http://opensource.org/licenses/cddl1.php
* See the License for the specific language governing permissions and limitations
* under the License.
*
* When distributing the Covered Code, include this CDDL Header Notice in each file
* and include the License file at http://opensource.org/licenses/cddl1.php.
* If applicable, add the following below this CDDL Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
* ====================
*/
package org.identityconnectors.flatfile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.identityconnectors.common.EqualsHashCodeBuilder;
import org.identityconnectors.framework.api.APIConfiguration;
import org.identityconnectors.framework.api.ConnectorFacade;
import org.identityconnectors.framework.api.ConnectorFacadeFactory;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeUtil;
import org.identityconnectors.framework.common.objects.ConnectorObject;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.identityconnectors.framework.common.objects.ResultsHandler;
import org.identityconnectors.framework.common.objects.filter.Filter;
import org.identityconnectors.test.common.TestHelpers;
import org.testng.AssertJUnit;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class FlatFileConnectorTests {
// =======================================================================
// Constants..
// =======================================================================
private static final String FILENAME = "test.csv";
private static final String CHANGE_NUMBER = "changeNumber";
private static final String ACCOUNTID = "accountid";
private static final String FIRSTNAME = "firstname";
private static final String LASTNAME = "lastname";
private static final String EMAIL = "email";
private static final char FIELD_DELIMITER = ',';
private static final char TEXT_QUALIFIER = '"';
private static final TestAccount HEADER = new TestAccount(ACCOUNTID, FIRSTNAME, LASTNAME, EMAIL,
CHANGE_NUMBER);
private static final Set<TestAccount> TEST_ACCOUNTS = new HashSet<TestAccount>();
static {
TEST_ACCOUNTS.add(new TestAccount("jpc4323435", "jPenelope", "jCruz",
"jxPenelope.Cruz@mail.com", "0"));
TEST_ACCOUNTS.add(new TestAccount("jkb3234416", "jKevin", "jBacon",
"jxKevin.Bacon@mail.com", "1"));
TEST_ACCOUNTS.add(new TestAccount("jpc4323436", "jPenelope", "jCruz2",
"jyPenelope.Cruz@mail.com", "2"));
TEST_ACCOUNTS.add(new TestAccount("jkb3234417", "jKevin", "jBacon,II",
"jyKevin.Bacon@mail.com", "3"));
TEST_ACCOUNTS.add(new TestAccount("jpc4323437", "jPenelope", "jCruz3",
"jzPenelope.Cruz@mail.com", "4"));
TEST_ACCOUNTS.add(new TestAccount("jkb3234419", "jKevin", "jBacon,III",
"jzKevin.Bacon@mail.com", "5"));
TEST_ACCOUNTS.add(new TestAccount("billy@bob.com", "jBilly", "jBob",
"jaBilly.Bob@mail.com", "6"));
TEST_ACCOUNTS.add(new TestAccount("bil@bob@bob.com", "jBillyBob", "jBobby",
"jaBillyBob.Bobby@mail.com", "7"));
};
// =======================================================================
// Setup/Tear down..
// =======================================================================
@BeforeMethod
public void createData() throws Exception {
// create a csv data file..
File f = getTestCSVFile();
// write out file data..
OutputStream fout = new FileOutputStream(getTestCSVFile());
Writer w = new OutputStreamWriter(fout, getUTF8Charset());
PrintWriter wrt = new PrintWriter(w);
// write out each user..
wrt.println(HEADER.toLine(FIELD_DELIMITER, TEXT_QUALIFIER));
for (TestAccount user : TEST_ACCOUNTS) {
String line = user.toLine(FIELD_DELIMITER, TEXT_QUALIFIER);
wrt.println(line);
}
wrt.close();
}
Charset getUTF8Charset() {
return Charset.forName("UTF-8");
}
// =======================================================================
// Tests
// =======================================================================
@Test
public void search() throws Exception {
// create the connector configuration..
FlatFileConfiguration config = new FlatFileConfiguration();
config.setFile(getTestCSVFile());
config.setUniqueAttributeName(ACCOUNTID);
config.validate();
// create a new connector..
FlatFileConnector cnt = new FlatFileConnector();
cnt.init(config);
// don't bother filtering the framework can do it..
Set<TestAccount> actual = new HashSet<TestAccount>();
List<ConnectorObject> results =
TestHelpers.searchToList(cnt, ObjectClass.ACCOUNT, new NoFilter());
for (ConnectorObject obj : results) {
actual.add(new TestAccount(obj));
}
cnt.dispose();
// print out the actual..
// System.out.println("Actual: " + actual);
// System.out.println("Expected: " + TEST_ACCOUNTS);
// attempt to see if they compare..
AssertJUnit.assertEquals(TEST_ACCOUNTS, actual);
}
static class NoFilter implements Filter {
public boolean accept(ConnectorObject obj) {
return true;
}
}
@Test
public void functional() throws Exception {
// create the connector configuration..
FlatFileConfiguration config = new FlatFileConfiguration();
config.setFile(getTestCSVFile());
config.setUniqueAttributeName(ACCOUNTID);
config.validate();
final Set<TestAccount> actual = new HashSet<TestAccount>();
ConnectorFacadeFactory factory = ConnectorFacadeFactory.getInstance();
// **test only**
APIConfiguration impl =
TestHelpers.createTestConfiguration(FlatFileConnector.class, config);
ConnectorFacade facade = factory.newInstance(impl);
facade.search(ObjectClass.ACCOUNT, new NoFilter(), new ResultsHandler() {
public boolean handle(ConnectorObject obj) {
actual.add(new TestAccount(obj));
return true;
}
}, null);
// print out the actual..
// System.out.println("Actual: " + actual);
// System.out.println("Expected: " + TEST_ACCOUNTS);
// attempt to see if they compare..
AssertJUnit.assertEquals(TEST_ACCOUNTS, actual);
}
// =======================================================================
// Helper Methods..
// =======================================================================
private File getTestCSVFile() throws Exception {
File testDir =
new File(URLDecoder.decode(FlatFileConnectorTests.class.getResource("/").getFile(),
"UTF-8"));
return new File(testDir, FILENAME);
}
private static class TestAccount {
private String changeNumber;
private String accountId;
private String firstName;
private String lastName;
private String email;
public TestAccount(String accountId, String firstName, String lastName, String email,
String changeNumber) {
this.accountId = accountId;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.changeNumber = changeNumber;
}
public TestAccount(ConnectorObject obj) {
accountId = obj.getUid().getUidValue();
// go through each of the other variables..
for (Attribute attr : obj.getAttributes()) {
if (CHANGE_NUMBER.equals(attr.getName())) {
changeNumber = AttributeUtil.getStringValue(attr);
} else if (FIRSTNAME.equals(attr.getName())) {
firstName = AttributeUtil.getStringValue(attr);
} else if (LASTNAME.equals(attr.getName())) {
lastName = AttributeUtil.getStringValue(attr);
} else if (EMAIL.equals(attr.getName())) {
email = AttributeUtil.getStringValue(attr);
}
}
}
public String getAccountId() {
return accountId;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getEmail() {
return email;
}
public String getChangeNumber() {
return changeNumber;
}
EqualsHashCodeBuilder getEqHash() {
EqualsHashCodeBuilder ret = new EqualsHashCodeBuilder();
ret.append(getAccountId());
ret.append(getFirstName());
ret.append(getLastName());
ret.append(getEmail());
ret.append(getChangeNumber());
return ret;
}
@Override
public boolean equals(Object obj) {
boolean ret = false;
if (obj instanceof TestAccount) {
ret = getEqHash().equals(((TestAccount) obj).getEqHash());
}
return ret;
}
@Override
public int hashCode() {
return getEqHash().hashCode();
}
@Override
public String toString() {
// poor man's to string..
Map<String, String> map = new HashMap<String, String>();
map.put("id", accountId);
map.put("changeNumber", changeNumber);
map.put("email", email);
map.put("firstName", firstName);
map.put("lastName", lastName);
return map.toString();
}
/**
* Create a string representation of a field, using the textQualifier if
* the fieldDelimiter is contained in the field's value.
*
* @param field
* String value of field to convert/externalize.
* @param fieldDelimiter
* delimiter used between fields
* @param textQualifier
* text qualifier to use as needed
* @return String representation of the field suitable for writing.
*/
static String getField(final String field, final char fieldDelimiter,
final char textQualifier) {
String result = field;
if ((field != null) && (field.indexOf(fieldDelimiter) > -1)) {
result = textQualifier + field + textQualifier;
}
return result;
}
public String toLine(final char fieldd, final char textq) {
StringBuffer buf = new StringBuffer();
buf.append(getField(getAccountId(), fieldd, textq));
buf.append(fieldd);
buf.append(getField(getFirstName(), fieldd, textq));
buf.append(fieldd);
buf.append(getField(getLastName(), fieldd, textq));
buf.append(fieldd);
buf.append(getField(getEmail(), fieldd, textq));
buf.append(fieldd);
buf.append(getField(getChangeNumber(), fieldd, textq));
return buf.toString();
}
}
}