001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *  
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *  
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License. 
018 *  
019 */
020package org.apache.directory.api.ldap.model.schema.syntaxCheckers;
021
022
023import org.apache.directory.api.ldap.model.constants.SchemaConstants;
024import org.apache.directory.api.ldap.model.schema.SyntaxChecker;
025import org.apache.directory.api.util.Strings;
026import org.slf4j.Logger;
027import org.slf4j.LoggerFactory;
028
029
030/**
031 * A SyntaxChecker which verifies that a value is a DSAQualitySyntax according to 
032 * http://tools.ietf.org/id/draft-ietf-asid-ldapv3-attributes-03.txt, par 5.2.2.2 :
033 * <pre>
034 * &lt;DsaQualitySyntax&gt; ::= &lt;DSAKeyword&gt; [ '#' &lt;description&gt; ]
035 *
036 * &lt;DSAKeyword&gt; ::= 'DEFUNCT' | 'EXPERIMENTAL' | 'BEST-EFFORT' |
037 *                  'PILOT-SERVICE' | 'FULL-SERVICE'
038 *
039 * &lt;description&gt; ::= encoded as a PrintableString
040 * </pre>
041 *
042 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
043 */
044@SuppressWarnings("serial")
045public class DsaQualitySyntaxSyntaxChecker extends SyntaxChecker
046{
047    /** A logger for this class */
048    private static final Logger LOG = LoggerFactory.getLogger( DsaQualitySyntaxSyntaxChecker.class );
049
050
051    /**
052     * Creates a new instance of DSAQualitySyntaxSyntaxChecker.
053     */
054    public DsaQualitySyntaxSyntaxChecker()
055    {
056        super( SchemaConstants.DSA_QUALITY_SYNTAX );
057    }
058
059
060    /**
061     * {@inheritDoc}
062     */
063    public boolean isValidSyntax( Object value )
064    {
065        String strValue = null;
066
067        if ( value == null )
068        {
069            LOG.debug( "Syntax invalid for 'null'" );
070            return false;
071        }
072
073        if ( value instanceof String )
074        {
075            strValue = ( String ) value;
076        }
077        else if ( value instanceof byte[] )
078        {
079            strValue = Strings.utf8ToString( ( byte[] ) value );
080        }
081        else
082        {
083            strValue = value.toString();
084        }
085
086        if ( strValue.length() < 7 )
087        {
088            LOG.debug( "Syntax invalid for '{}'", value );
089            return false;
090        }
091
092        String remaining = null;
093
094        switch ( strValue.charAt( 0 ) )
095        {
096            case 'B':
097                if ( !strValue.startsWith( "BEST-EFFORT" ) )
098                {
099                    LOG.debug( "Syntax invalid for '{}'", value );
100                    return false;
101                }
102
103                remaining = strValue.substring( "BEST-EFFORT".length() );
104                break;
105
106            case 'D':
107                if ( !strValue.startsWith( "DEFUNCT" ) )
108                {
109                    LOG.debug( "Syntax invalid for '{}'", value );
110                    return false;
111                }
112
113                remaining = strValue.substring( "DEFUNCT".length() );
114                break;
115
116            case 'E':
117                if ( !strValue.startsWith( "EXPERIMENTAL" ) )
118                {
119                    LOG.debug( "Syntax invalid for '{}'", value );
120                    return false;
121                }
122
123                remaining = strValue.substring( "EXPERIMENTAL".length() );
124                break;
125
126            case 'F':
127                if ( !strValue.startsWith( "FULL-SERVICE" ) )
128                {
129                    LOG.debug( "Syntax invalid for '{}'", value );
130                    return false;
131                }
132
133                remaining = strValue.substring( "FULL-SERVICE".length() );
134                break;
135
136            case 'P':
137                if ( !strValue.startsWith( "PILOT-SERVICE" ) )
138                {
139                    LOG.debug( "Syntax invalid for '{}'", value );
140                    return false;
141                }
142
143                remaining = strValue.substring( "PILOT-SERVICE".length() );
144                break;
145
146            default:
147                LOG.debug( "Syntax invalid for '{}'", value );
148                return false;
149        }
150
151        // Now, we might have a description separated from the keyword by a '#'
152        // but this is optional
153        if ( remaining.length() == 0 )
154        {
155            LOG.debug( "Syntax valid for '{}'", value );
156            return true;
157        }
158
159        if ( remaining.charAt( 0 ) != '#' )
160        {
161            // We were expecting a '#'
162            LOG.debug( "Syntax invalid for '{}'", value );
163            return false;
164        }
165
166        // Check that the description is a PrintableString
167        boolean result = Strings.isPrintableString( remaining.substring( 1 ) );
168
169        if ( result )
170        {
171            LOG.debug( "Syntax valid for '{}'", value );
172        }
173        else
174        {
175            LOG.debug( "Syntax invalid for '{}'", value );
176        }
177
178        return result;
179    }
180}