blob: 0eb59e3d8d9b1b9a7fa4a2742ec55dde0c793309 [file] [log] [blame]
// ============================================================================
//
//
// OpenLDAP Schema Parser
//
//
// ============================================================================
// $Rev$
// ============================================================================
header {
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
*
* https://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.directory.api.ldap.schema.converter;
import java.util.List ;
import java.util.ArrayList ;
import java.util.Collections;
import java.io.IOException;
import org.apache.directory.api.ldap.schema.converter.SchemaElement;
import org.apache.directory.api.ldap.model.schema.UsageEnum;
import org.apache.directory.api.ldap.model.schema.ObjectClassTypeEnum;
}
class antlrSchemaConverterLexer extends Lexer ;
options {
k = 7 ;
exportVocab=antlrSchema ;
charVocabulary = '\3'..'\377' ;
caseSensitive = false ;
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 antlrSchemaConverterParser extends Parser ;
options {
k = 5 ;
defaultErrorHandler = false ;
}
{
private List<SchemaElement> schemaElements = new ArrayList<SchemaElement>();
// ------------------------------------------------------------------------
// Public Methods
// ------------------------------------------------------------------------
public void clear()
{
schemaElements.clear();
}
public List<SchemaElement> getSchemaElements()
{
return Collections.unmodifiableList( schemaElements );
}
}
// ----------------------------------------------------------------------------
// Main Entry Point Production
// ----------------------------------------------------------------------------
parseSchema
:
( attributeType | objectClass )* "END"
;
// ----------------------------------------------------------------------------
// AttributeType Productions
// ----------------------------------------------------------------------------
objectClass
{
ObjectClassHolder objectClass = null;
}
:
"objectclass"
OPEN_PAREN oid:NUMERICOID
{
objectClass = new ObjectClassHolder( 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] )?
// @TODO : add ( extension[type] )*
CLOSE_PAREN
{
schemaElements.add( objectClass );
}
;
may [ObjectClassHolder objectClass]
{
List<String> list = null;
}
: "MAY" list=woidlist
{
objectClass.setMay( list );
}
;
must [ObjectClassHolder objectClass]
{
List<String> list = null;
}
: "MUST" list=woidlist
{
objectClass.setMust( list );
}
;
objectClassSuperiors [ObjectClassHolder objectClass]
{
List<String> list = null;
}
: "SUP" list=woidlist
{
objectClass.setSuperiors( list );
}
;
woid returns [String oid]
{
oid = null;
}
:
(
opt1:NUMERICOID
{
oid = opt1.getText();
}
|
opt2:IDENTIFIER
{
oid = opt2.getText();
}
)
;
woidlist returns [List<String> list]
{
list = new ArrayList<String>( 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 [ObjectClassHolder objectClass]
: d:DESC
{
String text = d.getText();
int start = text.indexOf( '\'' );
String desc = text.substring( start + 1, text.length() - 1 );
desc = desc.replace( "\\\"", "\"" );
desc = desc.replace( "\\'", "'" );
desc = desc.replace( "\\27", "'" );
desc = desc.replace( "\\5C", "\"" );
objectClass.setDescription( desc );
}
;
objectClassNames [ObjectClassHolder objectClass]
{
List<String> list = new ArrayList<String>();
}
:
(
"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( list );
}
;
// ----------------------------------------------------------------------------
// AttributeType Productions
// ----------------------------------------------------------------------------
attributeType
{
AttributeTypeHolder type = null;
}
:
"attributetype"
OPEN_PAREN oid:NUMERICOID
{
type = new AttributeTypeHolder( oid.getText() );
}
( names[type] )?
( attributeTypeDesc[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] )?
// @TODO : add ( extension[type] )*
CLOSE_PAREN
{
schemaElements.add( type );
}
;
attributeTypeDesc [AttributeTypeHolder type]
: d:DESC
{
String text = d.getText();
int start = text.indexOf( '\'' );
String desc = text.substring( start +1, text.length() - 1 );
desc = desc.replace( "\\\"", "\"" );
desc = desc.replace( "\\'", "'" );
desc = desc.replace( "\\27", "'" );
desc = desc.replace( "\\5C", "\"" );
type.setDescription( desc );
}
;
superior [AttributeTypeHolder type]
: "SUP"
(
oid:NUMERICOID
{
type.setSuperior( oid.getText() );
}
|
id:IDENTIFIER
{
type.setSuperior( id.getText() );
}
);
equality [AttributeTypeHolder type]
: "EQUALITY"
(
oid:NUMERICOID
{
type.setEquality( oid.getText() );
}
|
id:IDENTIFIER
{
type.setEquality( id.getText() );
}
);
substr [AttributeTypeHolder type]
: "SUBSTR"
(
oid:NUMERICOID
{
type.setSubstr( oid.getText() );
}
|
id:IDENTIFIER
{
type.setSubstr( id.getText() );
}
);
ordering [AttributeTypeHolder type]
: "ORDERING"
(
oid:NUMERICOID
{
type.setOrdering( oid.getText() );
}
|
id:IDENTIFIER
{
type.setOrdering( id.getText() );
}
);
names [AttributeTypeHolder type]
{
List<String> list = new ArrayList<String>();
}
:
"NAME"
(
QUOTE id0:IDENTIFIER QUOTE
{
list.add( id0.getText() );
}
|
( OPEN_PAREN
( QUOTE id1:IDENTIFIER
{
list.add( id1.getText() );
}
QUOTE
)+
CLOSE_PAREN )
)
{
type.setNames( list );
}
;
syntax [AttributeTypeHolder type]
: 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.setOidLen( Long.parseLong( length ) );
}
;
usage [AttributeTypeHolder type]
:
"USAGE"
(
"userApplications" { type.setUsage( UsageEnum.USER_APPLICATIONS ); } |
"directoryOperation" { type.setUsage( UsageEnum.DIRECTORY_OPERATION ); } |
"distributedOperation" { type.setUsage( UsageEnum.DISTRIBUTED_OPERATION ); } |
"dSAOperation" { type.setUsage( UsageEnum.DSA_OPERATION ); }
);