IComponent* ComponentBase::getOrCreateInternalComponent( const char* componentName, const char* interfaceName, const char* facetName ) { std::string fullTypeName( componentName ); // get the component if it already exists ITypeManager* tm = getSystem()->getTypes(); IType* type = tm->findType( fullTypeName ); if( type ) { assert( type->getKind() == TK_COMPONENT ); return static_cast<IComponent*>( type ); } // otherwise, create the component IType* itfType = getType( interfaceName ); assert( itfType->getKind() == TK_INTERFACE ); size_t lastDotPos = fullTypeName.rfind( '.' ); assert( lastDotPos != std::string::npos ); // componentName must be specified with a namespace std::string namespaceName( fullTypeName.substr( 0, lastDotPos ) ); std::string localTypeName( fullTypeName.substr( lastDotPos + 1 ) ); INamespace* ns = tm->findNamespace( namespaceName ); assert( ns ); // the namespace should have been created before RefPtr<ITypeBuilder> tb = ns->defineType( localTypeName, TK_COMPONENT ); tb->definePort( facetName, static_cast<IInterface*>( itfType ), true ); try { tm->getTransaction()->commit(); } catch( std::exception& ) { tm->getTransaction()->rollback(); throw; } type = tb->createType(); assert( type && type->getKind() == TK_COMPONENT ); // set the component with a basic reflector type->setReflector( BasicReflector::create( type ) ); return static_cast<IComponent*>( type ); }
void Loader::onPort( const location& loc, bool isFacet, const std::string& name ) { IType* type = getLastDeclaredType(); if( getError() ) return; if( type->getKind() != TK_INTERFACE ) { pushError( loc, "an interface type was expected" ); return; } CATCH_ERRORS( loc, _typeBuilder->definePort( name, static_cast<IInterface*>( type ), isFacet ) ); onElement( name ); }
void Loader::onRaises( const location& loc, const std::string& name ) { IType* type = resolveType( loc, name ); if( getError() ) return; if( !type ) { PUSH_ERROR( loc, "error loading exception type '" << name << "'" ); } else if( type->getKind() != TK_EXCEPTION ) { PUSH_ERROR( loc, "attempt to raise non-exception type '" << type->getFullName() << "'" ); } else { CATCH_ERRORS( loc, _methodBuilder->defineException( static_cast<IException*>( type ) ) ); } }
void Loader::onAnnotation( const location& loc, const std::string& name, bool hasData ) { std::string componentName; componentName.reserve( name.size() + 10 ); componentName.append( name ); componentName.append( "Annotation" ); IType* type = resolveType( loc, componentName ); if( !type ) { PUSH_ERROR( loc, "error loading annotation type '" << componentName << "'" ); return; } if( type->getKind() != TK_COMPONENT ) { PUSH_ERROR( loc, "annotation type '" << componentName << "' is not a component" ); return; } try { RefPtr<IAnnotation> annotation; if( hasData ) { RefPtr<IObject> object( type->getReflector()->newInstance() ); annotation = getAnnotationFrom( object.get() ); } else { annotation = getDefaultAnnotationInstance( type ); } if( _annotations.empty() ) _annotations.push_back( AnnotationRecord() ); _annotations.back().annotations.push_back( annotation.get() ); } catch( Exception& e ) { pushError( loc, e.getMessage() ); } }
IArray* TypeManager::getArrayOf( IType* elementType ) { if( !elementType ) CORAL_THROW( IllegalArgumentException, "null element type" ); const std::string& elementTypeName = elementType->getName(); std::string arrayName; arrayName.reserve( elementTypeName.length() + 2 ); arrayName.append( elementTypeName ); arrayName.append( "[]" ); Namespace* ns = static_cast<Namespace*>( elementType->getNamespace() ); // try to locate an existing array of this type IType* existingArrayType = ns->getType( arrayName ); if( existingArrayType ) { assert( existingArrayType->getKind() == TK_ARRAY ); return static_cast<IArray*>( existingArrayType ); } // otherwise, try to create it TypeKind kind = elementType->getKind(); if( kind == TK_ARRAY ) CORAL_THROW( IllegalArgumentException, "arrays of arrays are illegal" ); if( !isData( kind ) ) CORAL_THROW( IllegalArgumentException, "arrays of " << kind << "s are illegal" ); RefPtr<ArrayType> arrayType = new ArrayType; arrayType->setType( TK_ARRAY, elementType->getName() + "[]", ns ); arrayType->setElementType( elementType ); ns->addType( arrayType.get() ); return arrayType.get(); }