001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008-2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2012-2015 ForgeRock AS
026 */
027package org.opends.server.extensions;
028
029import java.util.List;
030import java.util.Set;
031
032import org.forgerock.i18n.LocalizableMessage;
033import org.forgerock.opendj.config.server.ConfigChangeResult;
034import org.forgerock.opendj.config.server.ConfigException;
035import org.forgerock.opendj.ldap.ResultCode;
036import org.opends.server.admin.server.ConfigurationChangeListener;
037import org.opends.server.admin.std.server.UserDefinedVirtualAttributeCfg;
038import org.opends.server.api.VirtualAttributeProvider;
039import org.opends.server.core.SearchOperation;
040import org.opends.server.types.*;
041
042/**
043 * This class implements a virtual attribute provider that allows administrators
044 * to define their own values that will be inserted into any entry that matches
045 * the criteria defined in the virtual attribute rule.  This can be used to
046 * provide functionality like Class of Service (CoS) in the Sun Java System
047 * Directory Server.
048 */
049public class UserDefinedVirtualAttributeProvider
050       extends VirtualAttributeProvider<UserDefinedVirtualAttributeCfg>
051       implements ConfigurationChangeListener<UserDefinedVirtualAttributeCfg>
052{
053  /** The current configuration for this virtual attribute provider. */
054  private UserDefinedVirtualAttributeCfg currentConfig;
055
056
057
058  /**
059   * Creates a new instance of this member virtual attribute provider.
060   */
061  public UserDefinedVirtualAttributeProvider()
062  {
063    super();
064
065    // All initialization should be performed in the
066    // initializeVirtualAttributeProvider method.
067  }
068
069
070
071  /** {@inheritDoc} */
072  @Override
073  public void initializeVirtualAttributeProvider(
074                            UserDefinedVirtualAttributeCfg configuration)
075         throws ConfigException, InitializationException
076  {
077    this.currentConfig = configuration;
078    configuration.addUserDefinedChangeListener(this);
079  }
080
081
082
083  /** {@inheritDoc} */
084  @Override
085  public void finalizeVirtualAttributeProvider()
086  {
087    currentConfig.removeUserDefinedChangeListener(this);
088  }
089
090
091
092  /** {@inheritDoc} */
093  @Override
094  public boolean isMultiValued()
095  {
096    return currentConfig == null || currentConfig.getValue().size() > 1;
097  }
098
099
100
101  /** {@inheritDoc} */
102  @Override
103  public Attribute getValues(Entry entry, VirtualAttributeRule rule)
104  {
105    Set<String> userDefinedValues = currentConfig.getValue();
106
107    switch (userDefinedValues.size()) {
108    case 0:
109      return Attributes.empty(rule.getAttributeType());
110    case 1:
111      String valueString = userDefinedValues.iterator().next();
112      return Attributes.create(rule.getAttributeType(), valueString);
113    default:
114      AttributeBuilder builder = new AttributeBuilder(rule.getAttributeType());
115      builder.addAllStrings(userDefinedValues);
116      return builder.toAttribute();
117    }
118  }
119
120
121
122  /** {@inheritDoc} */
123  @Override
124  public boolean isSearchable(VirtualAttributeRule rule,
125                              SearchOperation searchOperation,
126                              boolean isPreIndexed)
127  {
128    // We will not allow searches based only on user-defined virtual attributes.
129    return false;
130  }
131
132
133
134  /** {@inheritDoc} */
135  @Override
136  public void processSearch(VirtualAttributeRule rule,
137                            SearchOperation searchOperation)
138  {
139    searchOperation.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
140    return;
141  }
142
143
144
145  /** {@inheritDoc} */
146  @Override
147  public boolean isConfigurationChangeAcceptable(
148                      UserDefinedVirtualAttributeCfg configuration,
149                      List<LocalizableMessage> unacceptableReasons)
150  {
151    // The new configuration should always be acceptable.
152    return true;
153  }
154
155
156
157  /** {@inheritDoc} */
158  @Override
159  public ConfigChangeResult applyConfigurationChange(
160                                 UserDefinedVirtualAttributeCfg configuration)
161  {
162    // Just accept the new configuration as-is.
163    currentConfig = configuration;
164
165    return new ConfigChangeResult();
166  }
167}
168