: code generator tutorial

Lesson 7: Exclude Types From a Model

Invariably, you will run into situations where there are Java types that you are just not interested in, yet they keep appearing in your model because they are referenced by types that you are interested in. You are absolutely certain that you will never want to generate proxy types for these types and having them in your model makes everything consume more resources, take longer, and makes the model harder to understand.

To alleviate this problem, the code generator allows you to exclude Java types from import operations. Basically, whenever you import Java types into the model, excluded types are simply omitted. It is not as if they were missing but rather as if they did not exist at all.

The code generator is already configured to exclude some types. Here is the default value of the "Excluded Types" model property:

{
    exclude:'com.sun.**,sun.**,sunw.**',
    private:false,
    anonymous:false,
    annotation:false
}

This instructs the code generator to omit the internal Java implementation types that come with every JRE (in SUN packages) as well as private types, anonymous types, and annotation types. This is a good default value because explicit use of these types is either strongly discouraged or impossible, even in pure Java.

You can change the value of this property to omit fewer, more, or different types from the model. For example: you might have a very strong type naming policy for your own Java types. Any type whose name ends with Impl might be an implementation type that should not be considered for proxy generation because you only want to generate API types and not implementation types. You could modify the Excluded Types property to:

{
    exclude:'com.sun.**,sun.**,sunw.**,com.myfirm.**Impl',
    private:false,
    anonymous:false,
    annotation:false
}

Step by Step Instructions

  1. Start the Code Generator GUI

    To start the code generator, run xmog without the -version argument. Assuming you are still in the code generator's bin directory, simply type:

    xmog
    ./xmog

    If you run into problems please check out the first lesson.

  2. Open the Import Type(s) from Classpath Dialog

    Click the Add class icon toolbar icon or select Import Type(s) from Class Path... from the code generator's Edit menu. You should see this dialog displayed: The import types from classpath dialog

  3. Specify the Types You Want to Import

    We are just going to import all the types in the java.lang package, so we leave the Exclude field blank and enter java.lang.* in the Include field. Press OK.

    You should see something like this: The GUI after import

    We will focus on the types whose name starts with Class. You can see that there are several enabled types (Class, ClassCastException, ClassLoader, etc.) as well as a few disabled types (ClassCircularityError, ClassFormatError). Your exact results may vary based on the JRE you have configured.

    It's a bit contrived, but let's say that we never want to see these Class-related types in our model again. That's easily achievable via the Exclude Types model property.

  4. Start Over

    Close the code generator without saving the model and start over with a new model by repeating Step 1.

  5. Modify the Excluded Types Property

    Click in the new model's edit field for the "Excluded Types" model property. Change the exclude value by prepending java.lang.Class*,. This will prevent any types in the java.lang package whose name starts with Class from appearing in the model. The new value should look like this:

    {exclude:'java.lang.Class*,com.sun.**,sun.**,sunw.**', private:false, anonymous:false, annotation:false }
        
  6. Import Types

    Repeat Step 2 to perform the import operation of all types in the java.lang package. The resulting model will now look something like this: The GUI after import

    Note that all the types whose names start with Class are gone from the model. They are gone because these types satisfy the modified exclusion condition. Of course these types continue to exist as Java types and they will always be present in Java. It is simply our model that has been made unaware of the types' continued existence. Any code generation taking place now would not include any reference to the excluded types.

    You can't see it in the screenshot, but if there were types starting with Class in other packages, they would still be there. This is because we specified that we only wanted to exclude types starting with Class in the java.lang package. Had we wanted to exclude all types whose name starts with Class irrespective of their package, we could have used the pattern **.Class*.

Take-Away Points

  1. When You Should Consider Type Exclusion

    Beyond the types excluded by the default setting, you would typically consider excluding types by package. Frequently, you have entire packages that are of no interest for an integration project because they contain only types that deal with application internals like logging or tracing. There might also be packages that contain code that you don't want to expose, like application security. Not having such types be part of the model makes it much harder to accidentally enable them at a later point.

    You might also exclude all types that follow a certain naming policy. For example, you might have application internal class types that implement the interfaces that you wish to publish to another language via the code generator. Unfortunately, the implementation classes are in the same packages as the interfaces they implement so you cannot use a package pattern to exclude them. Fortunately, all your implementation classes follow the simple naming pattern <IfcName>Impl. This allows you to use an exclusion pattern of com.myapp.**Impl to exclude all types that are in your application's package hierarchy and whose name ends with Impl.

  2. When You Should Make Type Exclusion Less Restrictive

    There are a few cases where you might need to generate proxy types for types in the com.sun or sun packages. These cases typically involve use of types dealing with embedding Java GUI widgets in native GUI applications. Other than that, we have not yet encountered a legitimate use case for taking these types off the exclusion list.

  3. Feel Free to Use Type Name Patterns Liberally in Type Exclusion!

    >Whenever we have run into a good use case for type exclusion, it has been name pattern based. Think of examples like:

    • all types whose name ends with ____,
    • all types in package ____.
  4. How Is Type Exclusion Related to type Enablement?

    The two are related, but different. Only enabled types result in generated code. To be enabled, a type must be part of the model. To be part of the model, it must not be excluded. Type exclusion is the "nuclear option" of type disabling. If a type is excluded, it can never be enabled because there is nothing in the model that to be enabled. If a type is part of the model but it is disabled, it can be enabled as we have seen in lesson on type enablement.