package org.identityconnectors.oracle;
import static org.identityconnectors.oracle.OracleMessages.MSG_EAP_CANNOT_RESOLVE_SPI_OPERATION;
import static org.identityconnectors.oracle.OracleMessages.MSG_EAP_INVALID_ELEMENTS_IN_MAP;
import static org.identityconnectors.oracle.OracleMessages.MSG_EAP_MUST_SPECIFY_ONE_ARRAY_ELEMENT;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.identityconnectors.framework.common.FrameworkUtil;
import org.identityconnectors.framework.common.objects.ConnectorMessages;
import org.identityconnectors.framework.spi.operations.SPIOperation;
interface ExtraAttributesPolicySetup {
public ExtraAttributesPolicy getPolicy(OracleUserAttribute attribute,
Class<? extends SPIOperation> operation);
}
final class ExtraAttributesPolicySetupBuilder {
private final Map<Pair<OracleUserAttribute, Class<? extends SPIOperation>>, ExtraAttributesPolicy> policies;
private final ConnectorMessages cm;
ExtraAttributesPolicySetupBuilder(ConnectorMessages cm) {
policies =
new LinkedHashMap<Pair<OracleUserAttribute, Class<? extends SPIOperation>>, ExtraAttributesPolicy>();
this.cm = OracleConnectorHelper.assertNotNull(cm, "cm");
}
ExtraAttributesPolicySetup build() {
final Map<Pair<OracleUserAttribute, Class<? extends SPIOperation>>, ExtraAttributesPolicy> policies =
new LinkedHashMap<Pair<OracleUserAttribute, Class<? extends SPIOperation>>, ExtraAttributesPolicy>(
this.policies);
for (OracleUserAttribute attribute : OracleUserAttribute.values()) {
for (Class<? extends SPIOperation> operation : FrameworkUtil.allSPIOperations()) {
Pair<OracleUserAttribute, Class<? extends SPIOperation>> pair =
new Pair<OracleUserAttribute, Class<? extends SPIOperation>>(attribute,
operation);
ExtraAttributesPolicy policy = policies.get(pair);
if (policy == null) {
policy = attribute.getExtraAttributesPolicy(operation);
if (policy == null) {
policy = ExtraAttributesPolicy.FAIL;
}
policies.put(pair, policy);
}
}
}
return new ExtraAttributesPolicySetupImpl(policies);
}
@SuppressWarnings("unchecked")
ExtraAttributesPolicySetupBuilder parseArray(String[] policies) {
if (policies == null) {
return this;
}
for (String policy : policies) {
final Map<String, Object> map = MapParser.parseMap(policy, cm);
if (map.size() != 1) {
throw new IllegalArgumentException(cm.format(
MSG_EAP_MUST_SPECIFY_ONE_ARRAY_ELEMENT, null));
}
String attributeName = map.keySet().iterator().next();
Map<String, String> elementMap = (Map<String, String>) map.values().iterator().next();
parseAttributeMap(attributeName, elementMap);
}
return this;
}
private void parseAttributeMap(String attributeName, Map<String, String> elementMap) {
if ("ALL".equalsIgnoreCase(attributeName)) {
for (OracleUserAttribute attribute : OracleUserAttribute.values()) {
parseAttribute(attribute, elementMap, false);
}
return;
}
OracleUserAttribute attribute = OracleUserAttribute.valueOf(attributeName);
// Keys of the map should be simple names of SPIOperations
parseAttribute(attribute, elementMap, true);
}
private void parseAttribute(OracleUserAttribute attribute, Map<String, String> aElementMap,
boolean overwrite) {
Map<String, String> elementMap = new HashMap<String, String>(aElementMap);
for (Iterator<Entry<String, String>> i = elementMap.entrySet().iterator(); i.hasNext();) {
Entry<String, String> entry = i.next();
String opString = entry.getKey();
String policyString = entry.getValue();
ExtraAttributesPolicy policy = ExtraAttributesPolicy.valueOf(policyString);
Class<? extends SPIOperation> operation = resolveOperation(opString);
definePolicyInternal(attribute, operation, policy, overwrite);
i.remove();
}
if (!elementMap.isEmpty()) {
throw new IllegalArgumentException(cm.format(MSG_EAP_INVALID_ELEMENTS_IN_MAP, null,
elementMap));
}
}
private Class<? extends SPIOperation> resolveOperation(String opString) {
for (Class<? extends SPIOperation> clazz : FrameworkUtil.allSPIOperations()) {
if (clazz.getName().equals(opString)) {
return clazz;
}
;
String clazzSimpleName = clazz.getSimpleName();
if (clazzSimpleName.equals(opString)) {
return clazz;
}
if (clazzSimpleName.endsWith("Op")
&& clazzSimpleName.substring(0, clazzSimpleName.length() - 2).equalsIgnoreCase(
opString)) {
return clazz;
}
}
throw new IllegalArgumentException(cm.format(MSG_EAP_CANNOT_RESOLVE_SPI_OPERATION, null,
opString));
}
@SuppressWarnings("unchecked")
ExtraAttributesPolicySetupBuilder parseMap(String format) {
if ("default".equalsIgnoreCase(format)) {
return this;
}
final Map<String, Object> map = MapParser.parseMap(format, cm);
for (Iterator<Map.Entry<String, Object>> i = map.entrySet().iterator(); i.hasNext();) {
Entry<String, Object> entry = i.next();
String attributeName = entry.getKey();
Map<String, String> elementMap = (Map<String, String>) entry.getValue();
parseAttributeMap(attributeName, elementMap);
i.remove();
}
if (!map.isEmpty()) {
throw new IllegalArgumentException(cm
.format(MSG_EAP_INVALID_ELEMENTS_IN_MAP, null, map));
}
return this;
}
ExtraAttributesPolicySetupBuilder definePolicy(OracleUserAttribute attribute,
Class<? extends SPIOperation> operation, ExtraAttributesPolicy policy) {
definePolicyInternal(attribute, operation, policy, true);
return this;
}
ExtraAttributesPolicySetupBuilder clearPolicies() {
policies.clear();
return this;
}
private void definePolicyInternal(OracleUserAttribute attribute,
Class<? extends SPIOperation> operation, ExtraAttributesPolicy policy, boolean overwrite) {
Pair<OracleUserAttribute, Class<? extends SPIOperation>> pair =
new Pair<OracleUserAttribute, Class<? extends SPIOperation>>(attribute, operation);
if (!overwrite) {
if (policies.containsKey(pair)) {
return;
}
}
policies.put(pair, policy);
}
}
final class ExtraAttributesPolicySetupImpl implements ExtraAttributesPolicySetup {
private final Map<Pair<OracleUserAttribute, Class<? extends SPIOperation>>, ExtraAttributesPolicy> policies;
ExtraAttributesPolicySetupImpl(
Map<Pair<OracleUserAttribute, Class<? extends SPIOperation>>, ExtraAttributesPolicy> policies) {
this.policies =
new LinkedHashMap<Pair<OracleUserAttribute, Class<? extends SPIOperation>>, ExtraAttributesPolicy>(
policies);
}
public ExtraAttributesPolicy getPolicy(OracleUserAttribute attribute,
Class<? extends SPIOperation> operation) {
ExtraAttributesPolicy policy =
policies.get(new Pair<OracleUserAttribute, Class<? extends SPIOperation>>(
attribute, operation));
if (policy == null) {
// Internal error, need not localize
throw new IllegalArgumentException(MessageFormat.format(
"No policy defined for attribute [{0}] and operation [{1}]", attribute,
operation));
}
return policy;
}
}