private void writeClass()

in modello-plugins/modello-plugin-jpox/src/main/java/org/apache/archiva/redback/components/modello/jpox/JPoxJdoMappingModelloGenerator.java [274:507]


    private void writeClass( XMLWriter writer, ModelClass modelClass )
        throws ModelloException
    {
        JPoxClassMetadata jpoxMetadata = (JPoxClassMetadata) modelClass.getMetadata( JPoxClassMetadata.ID );

        if ( !jpoxMetadata.isEnabled() )
        {
            // Skip generation of those classes that are not enabled for the jpox plugin.
            return;
        }

        writer.startElement( "class" );

        writer.addAttribute( "name", modelClass.getName() );

        ModelClass persistenceCapableSuperclass = null;

        if ( modelClass.hasSuperClass() && modelClass.isInternalSuperClass() )
        {
            persistenceCapableSuperclass = getModel().getClass( modelClass.getSuperClass(), getGeneratedVersion() );
        }

        if ( persistenceCapableSuperclass != null )
        {
            String superPackageName =
                persistenceCapableSuperclass.getPackageName( isPackageWithVersion(), getGeneratedVersion() );

            writer.addAttribute( "persistence-capable-superclass",
                                 superPackageName + "." + persistenceCapableSuperclass.getName() );
        }

        writer.addAttribute( "detachable", String.valueOf( jpoxMetadata.isDetachable() ) );

        writer.addAttribute( "table", getTableName( modelClass, jpoxMetadata ) );

        // ----------------------------------------------------------------------
        // If this class has a primary key field mark make jpox manage the id
        // as a autoincrement variable
        // ----------------------------------------------------------------------

        List fields = Collections.unmodifiableList( modelClass.getFields( getGeneratedVersion() ) );

        // TODO: for now, assume that any primary key will be set in the super class
        // While it should be possible to have abstract super classes and have the
        // key defined in the sub class this is not implemented yet.

        boolean needInheritance = false;

        if ( persistenceCapableSuperclass == null )
        {
            if ( StringUtils.isNotEmpty( jpoxMetadata.getIdentityType() ) )
            {
                String identityType = jpoxMetadata.getIdentityType();
                if ( !IDENTITY_TYPES.contains( identityType ) )
                {
                    throw new ModelloException(
                        "The JDO mapping generator does not support the specified " + "class identity type '"
                            + identityType + "'. " + "Supported types: " + IDENTITY_TYPES
                    );
                }
                writer.addAttribute( "identity-type", identityType );
            }
            else if ( isInstantionApplicationType( modelClass ) )
            {
                writer.addAttribute( "identity-type", "application" );
            }
        }
        else
        {
            needInheritance = true;
        }

        if ( objectIdClassOverride != null )
        {
            if ( StringUtils.isNotEmpty( objectIdClassOverride ) )
            {
                writer.addAttribute( "objectid-class", jpoxMetadata.getIdentityClass() );
            }
        }
        else if ( StringUtils.isNotEmpty( jpoxMetadata.getIdentityClass() ) )
        {
            // Use user provided objectId class.
            writer.addAttribute( "objectid-class", jpoxMetadata.getIdentityClass() );
        }
        else
        {
            // Calculate the objectId class.

            List primaryKeys = getPrimaryKeyFields( modelClass );

            // TODO: write generation support for multi-primary-key support.
            //       would likely need to write a java class that can supply an ObjectIdentity
            //       to the jpox/jdo implementation.
            if ( primaryKeys.size() > 1 )
            {
                throw new ModelloException(
                    "The JDO mapping generator does not yet support Object Identifier generation " + "for the "
                        + primaryKeys.size() + " fields specified as <identifier> or "
                        + "with jpox.primary-key=\"true\""
                );
            }

            if ( primaryKeys.size() == 1 )
            {
                ModelField modelField = (ModelField) primaryKeys.get( 0 );
                String objectIdClass = (String) PRIMITIVE_IDENTITY_MAP.get( modelField.getType() );

                if ( StringUtils.isNotEmpty( objectIdClass ) )
                {
                    writer.addAttribute( "objectid-class", objectIdClass );
                }
            }
        }

        if ( needInheritance )
        {
            writer.startElement( "inheritance" );

            // TODO: The table strategy should be customizable
            // http://www.jpox.org/docs/1_1/inheritance.html - in particular
            // the strategy="subclass-table" and strategy="new-table" parts

            writer.addAttribute( "strategy", "new-table" );

            writer.endElement();
        }

        // ----------------------------------------------------------------------
        // Write all fields
        // ----------------------------------------------------------------------

        for ( Iterator it = fields.iterator(); it.hasNext(); )
        {
            ModelField modelField = (ModelField) it.next();

            writeModelField( writer, modelField );
        }

        // Write ignored fields.
        List ignoredFields = jpoxMetadata.getNotPersisted();
        if ( ignoredFields != null )
        {
            Iterator it = ignoredFields.iterator();
            while ( it.hasNext() )
            {
                String fieldName = (String) it.next();
                writer.startElement( "field" );
                writer.addAttribute( "name", fieldName );
                writer.addAttribute( "persistence-modifier", "none" );
                writer.endElement();
            }
        }

        // ----------------------------------------------------------------------
        // Write out the "detailed" fetch group. This group will by default
        // contain all fields in a object. The default fetch group will contain
        // all the primitives in a class as by JDO defaults.
        // ----------------------------------------------------------------------

        List detailedFields = new ArrayList();

        for ( Iterator it = fields.iterator(); it.hasNext(); )
        {
            ModelField field = (ModelField) it.next();

            if ( field.isPrimitive() )
            {
                continue;
            }

            if ( field instanceof ModelAssociation )
            {
                StoreAssociationMetadata storeMetadata = getAssociationMetadata( (ModelAssociation) field );

                if ( storeMetadata.isPart() != null && storeMetadata.isPart().booleanValue() )
                {
                    continue;
                }
            }

            detailedFields.add( field );
        }

        // ----------------------------------------------------------------------
        // Write all fetch groups
        // ----------------------------------------------------------------------

        // Write defaut detail fetch group
        writeFetchGroup( writer, modelClass.getName() + "_detail", detailedFields, true );

        // Write user fetch groups
        Map fetchsMap = new HashMap();

        for ( Iterator it = fields.iterator(); it.hasNext(); )
        {
            ModelField field = (ModelField) it.next();

            JPoxFieldMetadata jpoxFieldMetadata = (JPoxFieldMetadata) field.getMetadata( JPoxFieldMetadata.ID );

            List names = jpoxFieldMetadata.getFetchGroupNames();

            if ( names != null )
            {
                for ( Iterator i = names.iterator(); i.hasNext(); )
                {
                    String fetchGroupName = (String) i.next();

                    List fetchList;

                    if ( fetchsMap.get( fetchGroupName ) == null )
                    {
                        fetchList = new ArrayList();
                    }
                    else
                    {
                        fetchList = (List) fetchsMap.get( fetchGroupName );
                    }

                    fetchList.add( field );

                    fetchsMap.put( fetchGroupName, fetchList );
                }
            }
        }

        for ( Iterator it = fetchsMap.keySet().iterator(); it.hasNext(); )
        {
            String fetchName = (String) it.next();

            writeFetchGroup( writer, fetchName, (List) fetchsMap.get( fetchName ), false );
        }

        writer.endElement(); // class
    }