// ============================================================================ // // // OpenLDAP Schema Parser // // // ============================================================================ // $Rev$ // ============================================================================ header { /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /* * Keep the semicolon right next to the package name or else there will be a * bug that comes into the foreground in the new antlr release. */ package org.apache.ldap.server.tools.schema; import java.util.* ; import org.apache.ldap.common.schema.*; } class antlrOpenLdapSchemaLexer extends Lexer ; options { k = 7 ; exportVocab=antlrOpenLdapSchema ; charVocabulary = '\3'..'\377' ; caseSensitive = false ; //testLiterals = true ; defaultErrorHandler = false ; } WS : ( '#' (~'\n')* '\n' { newline(); } | ' ' | '\t' | '\r' '\n' { newline(); } | '\n' { newline(); } | '\r' { newline(); } ) {$setType(Token.SKIP);} //ignore this token ; QUOTE : '\'' ; DIGIT : '0' .. '9' ; DOLLAR : '$' ; OPEN_PAREN : '(' ; CLOSE_PAREN : ')' ; OPEN_BRACKET : '{' ; CLOSE_BRACKET : '}' ; protected NUMERIC_STRING : ('0' .. '9')+ ; NUMERICOID : NUMERIC_STRING ( '.' NUMERIC_STRING )+ ; IDENTIFIER options { testLiterals=true; } : ( 'a' .. 'z') ( 'a' .. 'z' | '0' .. '9' | '-' | ';' )* ; DESC : "desc" WS QUOTE ( ~'\'' )+ QUOTE ; SYNTAX : "syntax" WS NUMERICOID ( OPEN_BRACKET ( DIGIT )+ CLOSE_BRACKET )? ; class antlrOpenLdapSchemaParser extends Parser ; options { k = 5 ; defaultErrorHandler = false ; } { public static final String[] EMPTY = new String[0]; private Map attributeTypes = new HashMap(); private Map objectClasses = new HashMap(); private ParserMonitor monitor = null; // ------------------------------------------------------------------------ // Public Methods // ------------------------------------------------------------------------ public void clear() { attributeTypes.clear(); objectClasses.clear(); } public Map getAttributeTypes() { return Collections.unmodifiableMap( attributeTypes ); } public Map getObjectClasses() { return Collections.unmodifiableMap( objectClasses ); } public void setParserMonitor( ParserMonitor monitor ) { this.monitor = monitor; } // ------------------------------------------------------------------------ // Private Methods // ------------------------------------------------------------------------ private void matchedProduction( String msg ) { if ( null != monitor ) { monitor.matchedProduction( msg ); } } } // ---------------------------------------------------------------------------- // Main Entry Point Production // ---------------------------------------------------------------------------- parseSchema { } : ( attributeType | objectClass )* "END" ; // ---------------------------------------------------------------------------- // AttributeType Productions // ---------------------------------------------------------------------------- objectClass { matchedProduction( "objectClass()" ); ObjectClassLiteral objectClass = null; } : "objectclass" OPEN_PAREN oid:NUMERICOID { objectClass = new ObjectClassLiteral( oid.getText() ); } ( objectClassNames[objectClass] )? ( objectClassDesc[objectClass] )? ( "OBSOLETE" { objectClass.setObsolete( true ); } )? ( objectClassSuperiors[objectClass] )? ( "ABSTRACT" { objectClass.setClassType( ObjectClassTypeEnum.ABSTRACT ); } | "STRUCTURAL" { objectClass.setClassType( ObjectClassTypeEnum.STRUCTURAL ); } | "AUXILIARY" { objectClass.setClassType( ObjectClassTypeEnum.AUXILIARY ); } )? ( must[objectClass] )? ( may[objectClass] )? CLOSE_PAREN { objectClasses.put( objectClass.getOid(), objectClass ); } ; may [ObjectClassLiteral objectClass] { matchedProduction( "may(ObjectClassLiteral)" ) ; ArrayList list = null; } : "MAY" list=woidlist { objectClass.setMay( ( String[] ) list.toArray( EMPTY ) ); } ; must [ObjectClassLiteral objectClass] { matchedProduction( "must(ObjectClassLiteral)" ) ; ArrayList list = null; } : "MUST" list=woidlist { objectClass.setMust( ( String[] ) list.toArray( EMPTY ) ); } ; objectClassSuperiors [ObjectClassLiteral objectClass] { matchedProduction( "objectClassSuperiors(ObjectClassLiteral)" ) ; ArrayList list = null; } : "SUP" list=woidlist { objectClass.setSuperiors( ( String[] ) list.toArray( EMPTY ) ); } ; woid returns [String oid] { oid = null; matchedProduction( "woid()" ) ; } : ( opt1:NUMERICOID { oid = opt1.getText(); } | opt2:IDENTIFIER { oid = opt2.getText(); } ) ; woidlist returns [ArrayList list] { matchedProduction( "woidlist()" ) ; list = new ArrayList( 2 ); String oid = null; } : ( oid=woid { list.add( oid ); } | ( OPEN_PAREN oid=woid { list.add( oid ); } ( DOLLAR oid=woid { list.add( oid ); } )* CLOSE_PAREN ) ) ; objectClassDesc [ObjectClassLiteral objectClass] { matchedProduction( "desc(ObjectClassLiteral)" ) ; } : d:DESC { String desc = d.getText().split( "'" )[1]; String[] quoted = desc.split( "\"" ); if ( quoted.length == 1 ) { objectClass.setDescription( desc ); } else { StringBuffer buf = new StringBuffer(); for ( int ii = 0; ii < quoted.length; ii++ ) { if ( ii < quoted.length - 1 ) { buf.append( quoted[ii] ).append( "\\" ).append( "\"" ); } else { buf.append( quoted[ii] ); } } objectClass.setDescription( buf.toString() ); } } ; objectClassNames [ObjectClassLiteral objectClass] { matchedProduction( "names(ObjectClassLiteral)" ) ; ArrayList list = new ArrayList(); } : ( "NAME" ( QUOTE id0:IDENTIFIER QUOTE { list.add( id0.getText() ); } | ( OPEN_PAREN QUOTE id1:IDENTIFIER { list.add( id1.getText() ); } QUOTE ( QUOTE id2:IDENTIFIER QUOTE { list.add( id2.getText() ); } )* CLOSE_PAREN ) ) ) { objectClass.setNames( ( String[] ) list.toArray( EMPTY ) ); } ; // ---------------------------------------------------------------------------- // AttributeType Productions // ---------------------------------------------------------------------------- attributeType { matchedProduction( "attributeType()" ); AttributeTypeLiteral type = null; } : "attributetype" OPEN_PAREN oid:NUMERICOID { type = new AttributeTypeLiteral( oid.getText() ); } ( names[type] )? ( desc[type] )? ( "OBSOLETE" { type.setObsolete( true ); } )? ( superior[type] )? ( equality[type] )? ( ordering[type] )? ( substr[type] )? ( syntax[type] )? ( "SINGLE-VALUE" { type.setSingleValue( true ); } )? ( "COLLECTIVE" { type.setCollective( true ); } )? ( "NO-USER-MODIFICATION" { type.setNoUserModification( true ); } )? ( usage[type] )? CLOSE_PAREN { attributeTypes.put( type.getOid(), type ); } ; desc [AttributeTypeLiteral type] { matchedProduction( "desc(AttributeTypeLiteral)" ) ; } : d:DESC { String desc = d.getText().split( "'" )[1]; String[] quoted = desc.split( "\"" ); if ( quoted.length == 1 ) { type.setDescription( desc ); } else { StringBuffer buf = new StringBuffer(); for ( int ii = 0; ii < quoted.length; ii++ ) { if ( ii < quoted.length - 1 ) { buf.append( quoted[ii] ).append( "\\" ).append( "\"" ); } else { buf.append( quoted[ii] ); } } type.setDescription( buf.toString() ); } } ; superior [AttributeTypeLiteral type] { matchedProduction( "superior(AttributeTypeLiteral)" ) ; } : "SUP" ( oid:NUMERICOID { type.setSuperior( oid.getText() ); } | id:IDENTIFIER { type.setSuperior( id.getText() ); } ); equality [AttributeTypeLiteral type] { matchedProduction( "equality(AttributeTypeLiteral)" ) ; } : "EQUALITY" ( oid:NUMERICOID { type.setEquality( oid.getText() ); } | id:IDENTIFIER { type.setEquality( id.getText() ); } ); substr [AttributeTypeLiteral type] { matchedProduction( "substr(AttributeTypeLiteral)" ) ; } : "SUBSTR" ( oid:NUMERICOID { type.setSubstr( oid.getText() ); } | id:IDENTIFIER { type.setSubstr( id.getText() ); } ); ordering [AttributeTypeLiteral type] { matchedProduction( "ordering(AttributeTypeLiteral)" ) ; } : "ORDERING" ( oid:NUMERICOID { type.setOrdering( oid.getText() ); } | id:IDENTIFIER { type.setOrdering( id.getText() ); } ); names [AttributeTypeLiteral type] { matchedProduction( "names(AttributeTypeLiteral)" ) ; ArrayList list = new ArrayList(); } : "NAME" ( QUOTE id0:IDENTIFIER QUOTE { list.add( id0.getText() ); } | ( OPEN_PAREN ( QUOTE id1:IDENTIFIER { list.add( id1.getText() ); } QUOTE )+ CLOSE_PAREN ) ) { type.setNames( ( String[] ) list.toArray( EMPTY ) ); } ; syntax [AttributeTypeLiteral type] { matchedProduction( "syntax(AttributeTypeLiteral)" ) ; } : token:SYNTAX { String[] comps = token.getText().split( " " ); int index = comps[1].indexOf( "{" ); if ( index == -1 ) { type.setSyntax( comps[1] ); return; } String oid = comps[1].substring( 0, index ); String length = comps[1].substring( index + 1, comps[1].length() - 1 ); type.setSyntax( oid ); type.setLength( Integer.parseInt( length ) ); } ; usage [AttributeTypeLiteral type] { matchedProduction( "usage(AttributeTypeLiteral)" ) ; } : "USAGE" ( "userApplications" { type.setUsage( UsageEnum.USERAPPLICATIONS ); } | "directoryOperation" { type.setUsage( UsageEnum.DIRECTORYOPERATION ); } | "distributedOperation" { type.setUsage( UsageEnum.DISTRIBUTEDOPERATION ); } | "dSAOperation" { type.setUsage( UsageEnum.DSAOPERATION ); } );