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 2006-2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2013-2014 ForgeRock AS
026 */
027package org.opends.server.api;
028
029import java.util.Collections;
030import java.util.List;
031import java.util.Set;
032
033import org.forgerock.i18n.LocalizableMessage;
034import org.opends.server.admin.std.server.ExtendedOperationHandlerCfg;
035import org.forgerock.opendj.config.server.ConfigException;
036import org.opends.server.core.DirectoryServer;
037import org.opends.server.core.ExtendedOperation;
038import org.opends.server.types.InitializationException;
039
040/**
041 * This class defines the set of methods and structures that must be
042 * implemented by a Directory Server module that implements the
043 * functionality required for one or more types of extended
044 * operations.
045 *
046 * @param <T> The configuration class that will be provided to
047 *            initialize the handler.
048 */
049@org.opends.server.types.PublicAPI(
050     stability=org.opends.server.types.StabilityLevel.VOLATILE,
051     mayInstantiate=false,
052     mayExtend=true,
053     mayInvoke=false)
054public abstract class
055     ExtendedOperationHandler<T extends ExtendedOperationHandlerCfg>
056{
057
058  /** The default set of supported control OIDs for this extended op. */
059  private final Set<String> supportedControlOIDs;
060
061  /** The default set of supported feature OIDs for this extended op. */
062  private final Set<String> supportedFeatureOIDs = Collections.emptySet();
063
064  /**
065   * Builds an extended operation.
066   */
067  public ExtendedOperationHandler()
068  {
069    this.supportedControlOIDs = Collections.<String> emptySet();
070  }
071
072  /**
073   * Builds an extended operation.
074   *
075   * @param supportedControlOIDs
076   *          the default set of supported control OIDs for this extended op
077   */
078  public ExtendedOperationHandler(Set<String> supportedControlOIDs)
079  {
080    this.supportedControlOIDs = supportedControlOIDs != null ?
081        Collections.unmodifiableSet(supportedControlOIDs)
082        : Collections.<String> emptySet();
083  }
084
085  /**
086   * Initializes this extended operation handler based on the
087   * information in the provided configuration entry.  It should also
088   * register itself with the Directory Server for the particular
089   * kinds of extended operations that it will process.
090   *
091   * @param  config  The extended operation handler configuration that
092   *                 contains the information to use to initialize
093   *                 this extended operation handler.
094   *
095   * @throws  ConfigException  If an unrecoverable problem arises in
096   *                           the process of performing the
097   *                           initialization.
098   *
099   * @throws  InitializationException  If a problem occurs
100   *                                   during initialization that is
101   *                                   not related to the server
102   *                                   configuration.
103   */
104  public void initializeExtendedOperationHandler(T config)
105      throws ConfigException, InitializationException
106  {
107    DirectoryServer.registerSupportedExtension(getExtendedOperationOID(), this);
108    registerControlsAndFeatures();
109  }
110
111
112
113  /**
114   * Indicates whether the provided configuration is acceptable for
115   * this extended operation handler.  It should be possible to call
116   * this method on an uninitialized extended operation handler
117   * instance in order to determine whether the extended operation
118   * handler would be able to use the provided configuration.
119   * <BR><BR>
120   * Note that implementations which use a subclass of the provided
121   * configuration class will likely need to cast the configuration
122   * to the appropriate subclass type.
123   *
124   * @param  configuration        The extended operation handler
125   *                              configuration for which to make the
126   *                              determination.
127   * @param  unacceptableReasons  A list that may be used to hold the
128   *                              reasons that the provided
129   *                              configuration is not acceptable.
130   *
131   * @return  {@code true} if the provided configuration is acceptable
132   *          for this extended operation handler, or {@code false} if
133   *          not.
134   */
135  public boolean isConfigurationAcceptable(
136                      ExtendedOperationHandlerCfg configuration,
137                      List<LocalizableMessage> unacceptableReasons)
138  {
139    // This default implementation does not perform any special
140    // validation.  It should be overridden by extended operation
141    // handler implementations that wish to perform more detailed
142    // validation.
143    return true;
144  }
145
146
147
148  /**
149   * Performs any finalization that may be necessary for this extended
150   * operation handler.  By default, no finalization is performed.
151   */
152  public void finalizeExtendedOperationHandler()
153  {
154    DirectoryServer.deregisterSupportedExtension(getExtendedOperationOID());
155    deregisterControlsAndFeatures();
156  }
157
158
159
160  /**
161   * Processes the provided extended operation.
162   *
163   * @param  operation  The extended operation to be processed.
164   */
165  public abstract void processExtendedOperation(ExtendedOperation
166                                                     operation);
167
168
169
170  /**
171   * Retrieves the OIDs of the controls that may be supported by this
172   * extended operation handler.  It should be overridden by any
173   * extended operation handler which provides special support for one
174   * or more controls.
175   *
176   * @return  The OIDs of the controls that may be supported by this
177   *          extended operation handler.
178   */
179  public Set<String> getSupportedControls()
180  {
181    return supportedControlOIDs;
182  }
183
184
185
186  /**
187   * Indicates whether this extended operation handler supports the
188   * specified control.
189   *
190   * @param  controlOID  The OID of the control for which to make the
191   *                     determination.
192   *
193   * @return  {@code true} if this extended operation handler does
194   *          support the requested control, or {@code false} if not.
195   */
196  public final boolean supportsControl(String controlOID)
197  {
198    return getSupportedControls().contains(controlOID);
199  }
200
201
202
203  /**
204   * Retrieves the OIDs of the features that may be supported by this
205   * extended operation handler.
206   *
207   * @return  The OIDs of the features that may be supported by this
208   *          extended operation handler.
209   */
210  public Set<String> getSupportedFeatures()
211  {
212    return supportedFeatureOIDs;
213  }
214
215
216
217  /**
218   * Indicates whether this extended operation handler supports the
219   * specified feature.
220   *
221   * @param  featureOID  The OID of the feature for which to make the
222   *                     determination.
223   *
224   * @return  {@code true} if this extended operation handler does
225   *          support the requested feature, or {@code false} if not.
226   */
227  public final boolean supportsFeature(String featureOID)
228  {
229    return getSupportedFeatures().contains(featureOID);
230  }
231
232
233
234  /**
235   * If the extended operation handler defines any supported controls
236   * and/or features, then register them with the server.
237   */
238  private void registerControlsAndFeatures()
239  {
240    Set<String> controlOIDs = getSupportedControls();
241    if (controlOIDs != null)
242    {
243      for (String oid : controlOIDs)
244      {
245        DirectoryServer.registerSupportedControl(oid);
246      }
247    }
248
249    Set<String> featureOIDs = getSupportedFeatures();
250    if (featureOIDs != null)
251    {
252      for (String oid : featureOIDs)
253      {
254        DirectoryServer.registerSupportedFeature(oid);
255      }
256    }
257  }
258
259
260
261  /**
262   * If the extended operation handler defines any supported controls
263   * and/or features, then deregister them with the server.
264   */
265  private void deregisterControlsAndFeatures()
266  {
267    Set<String> controlOIDs = getSupportedControls();
268    if (controlOIDs != null)
269    {
270      for (String oid : controlOIDs)
271      {
272        DirectoryServer.deregisterSupportedControl(oid);
273      }
274    }
275
276    Set<String> featureOIDs = getSupportedFeatures();
277    if (featureOIDs != null)
278    {
279      for (String oid : featureOIDs)
280      {
281        DirectoryServer.deregisterSupportedFeature(oid);
282      }
283    }
284  }
285
286  /**
287   * Retrieves the name associated with this extended operation.
288   *
289   * @return  The name associated with this extended operation,
290   *          if any, or <CODE>null</CODE> if there is none.
291   */
292  public String getExtendedOperationName()
293  {
294    return null;
295  }
296
297  /**
298   * Retrieves the object OID associated with this extended operation.
299   *
300   * @return the oid associated with this extended operation, if any, or
301   *         <CODE>null</CODE> if there is none.
302   */
303  public String getExtendedOperationOID()
304  {
305    return null;
306  }
307}
308