package er.extensions.eof;
import com.webobjects.eoaccess.EOAttribute;
import com.webobjects.eoaccess.EOEntity;
/**
* <h1>ERXQueryEOAttribute.java</h1>
* <p style="max-width:700px">
* This subclass of EOAttribute allows you to define attributes with a definition
* such as "COUNT(DISTINCT lineItems.lineItemID)" that can later be used with
* ERXQuery.
* </p>
* <p style="max-width:700px">
* What makes this class different from EOAttribute is that you do not have to
* add the attribute to the entity but you do have to tell the attribute what
* entity to use via the setAdHocEntity() method. The entity is used when
* looking up the properties referenced in the definition of the attribute,
* i.e. "SUM(lineItems.extendedAmount)".
* </p>
* <p style="max-width:700px">
* Instances of this class can be used with ERXQuery's select() and groupBy()
* methods. Their names can be referenced by the orderings passed into
* the orderBy() method and by qualifiers passed into the where() and having()
* methods.
* </p>
* <p style="max-width:700px">
* This class provides a factory method to create an instance of this class
* which encapsulates the correct order in which the name, entity, prototype
* and definition must be set for the attribute to work properly during
* SQL generation.
* </p>
*
* @author Ricardo J. Parada
*/
@SuppressWarnings("javadoc")
public class ERXQueryEOAttribute extends EOAttribute {
protected void setAdHocEntity(EOEntity entity) {
_parent = entity;
}
/**
* Override to make sure that simple definitions like "SYSDATE" work okay.
*/
@Override
public void setDefinition(String definition) {
// If the definition becomes null after setting it then let's try using the
// readFormat instead. For example, super.setDefinition("SYSDATE") does not work. On
// the other hand calling setReadFormat("SYSDATE") and setColumnName("") does the
// trick. In general super.setDefinition(definition) does not seem to work for
// simple oracle function that don't even have parenthesis like "SYSDATE".
super.setDefinition(definition);
// If the definition was not set above then wrap it in parenthesis
if (definition() == null) {
setReadFormat(definition);
setColumnName("");
}
}
// Factory method
/**
* Creates an instance of this class with the given name, definition and prototype
* attribute name. For example:
* <pre>
* {@code
* EOAttribute attr =
* ERXQueryEOAttribute.create(
* claimEntity, "totalExpectedAmount", "SUM(expectedAmount)", "currencyAmount2"
* );
* }
* </pre>
*/
public static EOAttribute create(EOEntity entity, String name, String definition, String prototypeAttributeName) {
// Get prototype attribute
EOAttribute prototype = entity.model().prototypeAttributeNamed(prototypeAttributeName);
// Create attribute, set name and ad hoc entity *immediately before*
// setting the prototype and the definition
ERXQueryEOAttribute attr = new ERXQueryEOAttribute();
attr.setName(name);
attr.setAdHocEntity(entity);
// The prototype must be set *after* the ad hoc entity
attr.setPrototype(prototype);
// The definition must be set *after* the prototype
attr.setDefinition(definition);
return attr;
}
public static ERXQueryEOAttribute create(EOEntity entity, String name, String definition, EOAttribute similarAttribute) {
// Create attribute, set name and ad hoc entity *immediately before*
// setting the prototype and the definition
ERXQueryEOAttribute attr = new ERXQueryEOAttribute();
attr.setName(name);
attr.setAdHocEntity(entity);
// The prototype must be set *after* the ad hoc entity
EOAttribute prototype = similarAttribute.prototype();
if (prototype != null) {
attr.setPrototype(prototype);
} else {
attr.setClassName(similarAttribute.className());
attr.setExternalType(similarAttribute.externalType());
attr.setValueFactoryMethodName(similarAttribute.valueFactoryMethodName());
attr.setFactoryMethodArgumentType(similarAttribute.factoryMethodArgumentType());
attr.setAdaptorValueConversionClassName(similarAttribute.adaptorValueConversionClassName());
attr.setAdaptorValueConversionMethodName(similarAttribute.adaptorValueConversionMethodName());
attr.setValueType(similarAttribute.valueType());
attr.setWidth(similarAttribute.width());
attr.setPrecision(similarAttribute.precision());
}
// The definition must be set *after* the prototype
attr.setDefinition(definition);
return attr;
}
}