# Maintaining General-Purpose Maintenance Classes

While most page maintenance classes are Entity-based (see Maintaining MO's below), it is sometimes necessary to write a general-purpose maintenance class for some specific purpose.

To develop such a Page Maintenance class, you need to create a hand-coded implementation class. This class subclasses a class (to be generated) with the same name (and package) as your class, but with the suffix "_Gen". For example, if your class is named `SamplePageMaintenance`, you'll subclass `SamplePageMaintenance_Gen`. Your class must include an annotation providing the metadata that describes the maintenance. This annotation is essentially a subset of the annotation for an entity page maintenance (MO maintenance), but leaves out details specific to the entity model (also known as the domain model). For example, the `RowField` annotation is not supported, since it links directly to an entity.

Here is an example of a simple `PageMaintenance` annotation:

    			@PageMaintenance (secured = false, service = CILABCDE,
    			      body = @DataElement (contents = { @DataField (name = DATA_FIELD1, overrideFieldName = FLD_NAME)
    			                  , @DataField (DATA_VALUE1)}),
    			      actions = { "read"},
    			      header = { @DataField (name = INPUT_FIELD1, overrideFieldName = FLD_NAME)
    			            , @DataField (name = INPUT_VALUE1)},
    			      headerFields = { @DataField (name = CONTEXT_NAME1, overrideFieldName = FLD_NAME)
    			            , @DataField (name = CONTEXT_VALUE1, overrideFieldName = FK_VALUE1)
    			            , @DataField (name = CONTEXT_NAME2, overrideFieldName = FLD_NAME)
    			            , @DataField (name = CONTEXT_VALUE10, overrideFieldName = FK_VALUE1)},
    			      modules = { "foundation"})

This example does not use any lists, but they are described and supported as are any entity maintenance classes. By default, any lists here are unmapped, that is, they are not populated by the framework from the entity model.

The supported actions are `read`, `change`, `add`, and `delete`. You can leave out the actions annotation completely if you intend to support all four of these actions. Otherwise, it's useful to declare what methods you'll support, so the framework can create an appropriate error message when an unsupported method is invoked.

You must implement one or more of the following action methods.

    			protected DataElement read(PageHeader header)
    			protected void change(DataElement item)
    			protected PageHeader add(DataElement item)
    			protected PageHeader copy(PageHeader header)
    			protected void delete(DataElement item)

The body of the implementation is completely up to you. The available API is largely the same as for entity page maintenance. For example, if you have a current session/transaction in which to execute queries, you can access the entity model. You are expected to throw `ApplicationError` or `ApplicationWarning` Java exceptions, as appropriate (for examplle, via `addError()` and `addWarning()`), unless a serious or unforeseen problem occurs, in which case you should throw a `LoggedException`, or simply let the underlying Java runtime exception bubble up.

The usual implementation of the read method would be to retrieve one or more parameters from the input page header, and construct a `DataElement` holding the desired return values, including any lists (which may be recursive).

For the `change` method, the usual behavior would be to examine the provided `DataElement` object, perform some operation, and return a different data element to hold the changed values.

The add method is similar to change in that it accepts an input `DataElement`, and returns the newly added `DataElement` instance (which should be a different instance than the input).

The `delete` method accepts a `DataElement`, but returns nothing after the conclusion of the operation.

Parent topic: Cookbook