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-2008 Sun Microsystems, Inc. 025 * Portions Copyright 2012-2015 ForgeRock AS 026 */ 027package org.opends.server.schema; 028 029import static org.opends.server.schema.SchemaConstants.*; 030 031import java.util.List; 032 033import org.forgerock.i18n.LocalizableMessage; 034import org.forgerock.opendj.config.server.ConfigChangeResult; 035import org.forgerock.opendj.config.server.ConfigException; 036import org.forgerock.opendj.ldap.schema.Schema; 037import org.forgerock.opendj.ldap.schema.SchemaOptions; 038import org.forgerock.opendj.ldap.schema.Syntax; 039import org.forgerock.util.Option; 040import org.opends.server.admin.server.ConfigurationChangeListener; 041import org.opends.server.admin.std.server.TelephoneNumberAttributeSyntaxCfg; 042import org.opends.server.api.AttributeSyntax; 043import org.opends.server.core.ServerContext; 044 045/** 046 * This class implements the telephone number attribute syntax, which is defined 047 * in RFC 2252. Note that this can have two modes of operation, depending on 048 * its configuration. Most of the time, it will be very lenient when deciding 049 * what to accept, and will allow anything but only pay attention to the digits. 050 * However, it can also be configured in a "strict" mode, in which case it will 051 * only accept values in the E.123 international telephone number format. 052 */ 053public class TelephoneNumberSyntax 054 extends AttributeSyntax<TelephoneNumberAttributeSyntaxCfg> 055 implements ConfigurationChangeListener<TelephoneNumberAttributeSyntaxCfg> 056{ 057 058 /** Indicates whether this matching rule should operate in strict mode. */ 059 private boolean strictMode; 060 061 /** The current configuration for this telephone number syntax. */ 062 private TelephoneNumberAttributeSyntaxCfg currentConfig; 063 064 private ServerContext serverContext; 065 066 /** 067 * Creates a new instance of this syntax. Note that the only thing that 068 * should be done here is to invoke the default constructor for the 069 * superclass. All initialization should be performed in the 070 * <CODE>initializeSyntax</CODE> method. 071 */ 072 public TelephoneNumberSyntax() 073 { 074 super(); 075 } 076 077 /** {@inheritDoc} */ 078 @Override 079 public void initializeSyntax(TelephoneNumberAttributeSyntaxCfg configuration, ServerContext serverContext) 080 throws ConfigException 081 { 082 this.serverContext = serverContext; 083 084 // We may or may not have access to the config entry. If we do, then see if 085 // we should use the strict compliance mode. If not, just assume that we 086 // won't. 087 strictMode = false; 088 if (configuration != null) 089 { 090 currentConfig = configuration; 091 currentConfig.addTelephoneNumberChangeListener(this); 092 strictMode = currentConfig.isStrictFormat(); 093 updateNewSchema(); 094 } 095 } 096 097 /** Update the option in new schema if it changes from current value. */ 098 private void updateNewSchema() 099 { 100 Option<Boolean> option = SchemaOptions.ALLOW_NON_STANDARD_TELEPHONE_NUMBERS; 101 if (strictMode == serverContext.getSchemaNG().getOption(option)) 102 { 103 SchemaUpdater schemaUpdater = serverContext.getSchemaUpdater(); 104 schemaUpdater.updateSchema(schemaUpdater.getSchemaBuilder().setOption(option, !strictMode).toSchema()); 105 } 106 } 107 108 /** {@inheritDoc} */ 109 @Override 110 public Syntax getSDKSyntax(Schema schema) 111 { 112 return schema.getSyntax(SchemaConstants.SYNTAX_TELEPHONE_OID); 113 } 114 115 /** 116 * Performs any finalization that may be necessary for this attribute syntax. 117 */ 118 @Override 119 public void finalizeSyntax() 120 { 121 currentConfig.removeTelephoneNumberChangeListener(this); 122 } 123 124 /** 125 * Retrieves the common name for this attribute syntax. 126 * 127 * @return The common name for this attribute syntax. 128 */ 129 @Override 130 public String getName() 131 { 132 return SYNTAX_TELEPHONE_NAME; 133 } 134 135 /** 136 * Retrieves the OID for this attribute syntax. 137 * 138 * @return The OID for this attribute syntax. 139 */ 140 @Override 141 public String getOID() 142 { 143 return SYNTAX_TELEPHONE_OID; 144 } 145 146 /** 147 * Retrieves a description for this attribute syntax. 148 * 149 * @return A description for this attribute syntax. 150 */ 151 @Override 152 public String getDescription() 153 { 154 return SYNTAX_TELEPHONE_DESCRIPTION; 155 } 156 157 /** {@inheritDoc} */ 158 @Override 159 public boolean isConfigurationChangeAcceptable( 160 TelephoneNumberAttributeSyntaxCfg configuration, 161 List<LocalizableMessage> unacceptableReasons) 162 { 163 // The configuration will always be acceptable. 164 return true; 165 } 166 167 /** {@inheritDoc} */ 168 @Override 169 public ConfigChangeResult applyConfigurationChange( 170 TelephoneNumberAttributeSyntaxCfg configuration) 171 { 172 currentConfig = configuration; 173 strictMode = configuration.isStrictFormat(); 174 updateNewSchema(); 175 176 return new ConfigChangeResult(); 177 } 178} 179