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.shared.ldap.model.schema.syntaxCheckers; 021 022 023import org.apache.directory.shared.asn1.util.Oid; 024import org.apache.directory.shared.ldap.model.constants.SchemaConstants; 025import org.apache.directory.shared.ldap.model.schema.SyntaxChecker; 026import org.apache.directory.shared.util.Strings; 027import org.slf4j.Logger; 028import org.slf4j.LoggerFactory; 029 030 031/** 032 * A SyntaxChecker which verifies that a value is a numeric oid and a length 033 * constraint according to RFC 4512. 034 * 035 * From RFC 4512 : 036 * 037 * noidlen = numericoid [ LCURLY len RCURLY ] 038 * numericoid = number 1*( DOT number ) 039 * len = number 040 * number = DIGIT | ( LDIGIT 1*DIGIT ) 041 * DIGIT = %x30 | LDIGIT ; "0"-"9" 042 * LDIGIT = %x31-39 ; "1"-"9" 043 * DOT = %x2E ; period (".") 044 * LCURLY = %x7B ; left curly brace "{" 045 * RCURLY = %x7D ; right curly brace "}" 046 * 047 * 048 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 049 */ 050@SuppressWarnings("serial") 051public class OidLenSyntaxChecker extends SyntaxChecker 052{ 053 /** A logger for this class */ 054 private static final Logger LOG = LoggerFactory.getLogger( OidLenSyntaxChecker.class ); 055 056 /** 057 * 058 * Creates a new instance of OidLenSyntaxChecker. 059 * 060 */ 061 public OidLenSyntaxChecker() 062 { 063 super( SchemaConstants.OID_LEN_SYNTAX ); 064 } 065 066 067 /** 068 * {@inheritDoc} 069 */ 070 public boolean isValidSyntax( Object value ) 071 { 072 String strValue = null; 073 074 if ( value == null ) 075 { 076 LOG.debug( "Syntax invalid for 'null'" ); 077 return false; 078 } 079 080 if ( value instanceof String ) 081 { 082 strValue = ( String ) value; 083 } 084 else if ( value instanceof byte[] ) 085 { 086 strValue = Strings.utf8ToString((byte[]) value); 087 } 088 else 089 { 090 strValue = value.toString(); 091 } 092 093 if ( strValue.length() == 0 ) 094 { 095 LOG.debug( "Syntax invalid for '{}'", value ); 096 return false; 097 } 098 099 // We are looking at the first position of the len part 100 int pos = strValue.indexOf( '{' ); 101 102 if ( pos < 0 ) 103 { 104 // Not found ... but it may still be a valid OID 105 boolean result = Oid.isOid(strValue); 106 107 if ( result ) 108 { 109 LOG.debug( "Syntax valid for '{}'", value ); 110 } 111 else 112 { 113 LOG.debug( "Syntax invalid for '{}'", value ); 114 } 115 116 return result; 117 } 118 else 119 { 120 // we should have a len value. First check that the OID is valid 121 String oid = strValue.substring( 0, pos ); 122 123 if ( !Oid.isOid( oid ) ) 124 { 125 LOG.debug( "Syntax invalid for '{}'", value ); 126 return false; 127 } 128 129 String len = strValue.substring( pos ); 130 131 // We must have a lnumber and a '}' at the end 132 if ( len.charAt( len.length() -1 ) != '}' ) 133 { 134 // No final '}' 135 LOG.debug( "Syntax invalid for '{}'", value ); 136 return false; 137 } 138 139 for ( int i = 1; i < len.length() - 1; i++ ) 140 { 141 switch ( len.charAt(i) ) 142 { 143 case '0': case '1': case '2' : case '3': case '4': 144 case '5': case '6': case '7' : case '8': case '9': 145 break; 146 147 default: 148 LOG.debug( "Syntax invalid for '{}'", value ); 149 return false; 150 } 151 } 152 153 if ( ( len.charAt( 1 ) == '0' ) && len.length() > 3 ) 154 { 155 // A number can't start with a '0' unless it's the only 156 // number 157 LOG.debug( "Syntax invalid for '{}'", value ); 158 return false; 159 } 160 161 LOG.debug( "Syntax valid for '{}'", value ); 162 return true; 163 } 164 } 165}