/*
* ====================
* 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.spml;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.identityconnectors.common.script.ScriptExecutor;
import org.identityconnectors.common.script.ScriptExecutorFactory;
import org.identityconnectors.framework.common.exceptions.ConnectorException;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.Uid;
import org.identityconnectors.framework.common.objects.filter.AbstractFilterTranslator;
import org.identityconnectors.framework.common.objects.filter.ContainsFilter;
import org.identityconnectors.framework.common.objects.filter.EndsWithFilter;
import org.identityconnectors.framework.common.objects.filter.EqualsFilter;
import org.identityconnectors.framework.common.objects.filter.GreaterThanOrEqualFilter;
import org.identityconnectors.framework.common.objects.filter.LessThanOrEqualFilter;
import org.identityconnectors.framework.common.objects.filter.StartsWithFilter;
import org.openspml.v2.profiles.dsml.And;
import org.openspml.v2.profiles.dsml.DSMLProfileException;
import org.openspml.v2.profiles.dsml.DSMLValue;
import org.openspml.v2.profiles.dsml.EqualityMatch;
import org.openspml.v2.profiles.dsml.FilterItem;
import org.openspml.v2.profiles.dsml.GreaterOrEqual;
import org.openspml.v2.profiles.dsml.LessOrEqual;
import org.openspml.v2.profiles.dsml.Or;
import org.openspml.v2.profiles.dsml.Substrings;
public class SpmlFilterTranslator extends AbstractFilterTranslator<FilterItem> {
private final ScriptExecutorFactory scriptExecutorFactory;
private final SpmlConnection connection;
private final SpmlConfiguration configuration;
private final ScriptExecutor mapQueryNameExecutor;
public SpmlFilterTranslator(final SpmlConfiguration configuration,
final SpmlConnection connection) {
this.connection = connection;
this.configuration = configuration;
scriptExecutorFactory =
ScriptExecutorFactory.newInstance(configuration.getScriptingLanguage());
try {
String mapQueryNameCommand = this.configuration.getMapQueryNameCommand();
if (mapQueryNameCommand != null && mapQueryNameCommand.length() > 0) {
mapQueryNameExecutor =
scriptExecutorFactory.newScriptExecutor(getClass().getClassLoader(),
mapQueryNameCommand, true);
} else {
mapQueryNameExecutor = null;
}
} catch (Exception e) {
throw new ConnectorException(this.configuration
.getMessage(SpmlMessages.MAPQUERYNAME_SCRIPT_ERROR), e);
}
}
@Override
protected FilterItem createAndExpression(FilterItem leftExpression, FilterItem rightExpression) {
if (leftExpression != null && rightExpression != null) {
And and = new And(new FilterItem[] { leftExpression, rightExpression });
return and;
} else if (leftExpression != null) {
return leftExpression;
} else if (rightExpression != null) {
return rightExpression;
} else {
return super.createAndExpression(leftExpression, rightExpression);
}
}
@Override
protected FilterItem createOrExpression(FilterItem leftExpression, FilterItem rightExpression) {
if (leftExpression != null && rightExpression != null) {
Or or = new Or(new FilterItem[] { leftExpression, rightExpression });
return or;
} else {
return super.createOrExpression(leftExpression, rightExpression);
}
}
@Override
protected FilterItem createStartsWithExpression(StartsWithFilter filter, boolean not) {
Attribute attribute = filter.getAttribute();
List<Object> value = attribute.getValue();
try {
if (!not && isSingleString(value)) {
return new Substrings(mapQueryName(attribute.getName()), new DSMLValue(
(String) value.get(0)), new DSMLValue[0], null);
} else {
return super.createStartsWithExpression(filter, not);
}
} catch (DSMLProfileException e) {
throw ConnectorException.wrap(e);
}
}
@Override
protected FilterItem createContainsExpression(ContainsFilter filter, boolean not) {
Attribute attribute = filter.getAttribute();
List<Object> value = attribute.getValue();
try {
if (!not && isSingleString(value)) {
return new Substrings(mapQueryName(attribute.getName()), null,
new DSMLValue[] { new DSMLValue((String) value.get(0)) }, null);
} else {
return super.createContainsExpression(filter, not);
}
} catch (DSMLProfileException e) {
throw ConnectorException.wrap(e);
}
}
@Override
protected FilterItem createEndsWithExpression(EndsWithFilter filter, boolean not) {
Attribute attribute = filter.getAttribute();
List<Object> value = attribute.getValue();
try {
if (!not && isSingleString(value)) {
return new Substrings(mapQueryName(attribute.getName()), null, new DSMLValue[0],
new DSMLValue((String) value.get(0)));
} else {
return super.createEndsWithExpression(filter, not);
}
} catch (DSMLProfileException e) {
throw ConnectorException.wrap(e);
}
}
@Override
protected FilterItem createEqualsExpression(EqualsFilter filter, boolean not) {
Attribute attribute = filter.getAttribute();
List<Object> value = attribute.getValue();
try {
if (!not && isSingleString(value)) {
return new EqualityMatch(mapQueryName(attribute.getName()), new DSMLValue(
(String) value.get(0)));
} else {
return super.createEqualsExpression(filter, not);
}
} catch (DSMLProfileException e) {
throw ConnectorException.wrap(e);
}
}
@Override
protected FilterItem createGreaterThanOrEqualExpression(GreaterThanOrEqualFilter filter,
boolean not) {
Attribute attribute = filter.getAttribute();
List<Object> value = attribute.getValue();
try {
if (!not && isSingleString(value)) {
GreaterOrEqual goe = new GreaterOrEqual();
goe.setName(mapQueryName(attribute.getName()));
goe.setValue(new DSMLValue((String) value.get(0)));
return goe;
} else {
return super.createGreaterThanOrEqualExpression(filter, not);
}
} catch (DSMLProfileException e) {
throw ConnectorException.wrap(e);
}
}
@Override
protected FilterItem createLessThanOrEqualExpression(LessThanOrEqualFilter filter, boolean not) {
Attribute attribute = filter.getAttribute();
List<Object> value = attribute.getValue();
try {
if (!not && isSingleString(value)) {
LessOrEqual loe = new LessOrEqual();
loe.setName(mapQueryName(attribute.getName()));
loe.setValue(new DSMLValue((String) value.get(0)));
return loe;
} else {
return super.createLessThanOrEqualExpression(filter, not);
}
} catch (DSMLProfileException e) {
throw ConnectorException.wrap(e);
}
}
private String mapQueryName(String name) {
if (Uid.NAME.equals(name)) {
return SpmlConnector.PSOID;
}
try {
if (mapQueryNameExecutor != null) {
Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("name", name);
arguments.put("configuration", configuration);
arguments.put("memory", connection.getMemory());
return (String) mapQueryNameExecutor.execute(arguments);
}
} catch (Exception e) {
throw new ConnectorException(configuration
.getMessage(SpmlMessages.MAPQUERYNAME_SCRIPT_ERROR), e);
}
return name;
}
private boolean isSingleString(List<Object> value) {
return value != null && value.size() == 1 && value.get(0) instanceof String;
}
}