Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
<#include "license.ftl">
<@license/>
<#assign object = doc.object>
package ${object.@package}.model.base;
<#if object.attributes.html[0]??>
import redora.util.HtmlSanitizer;
<#list doc["/object/attributes/enum[@scope='global']"] as enum>
import ${object.@package}.model.enums.${enum.@class};
import redora.exceptions.*;
import ${object.@package}.service.*;
<#if object.attributes.set[0]??>
import redora.set.*;
import java.sql.ResultSet;
import java.util.Date;
import java.util.EnumMap;
import java.util.Map;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import redora.api.*;
<#if object.attributes.date[0]?? || object.attributes.datetime[0]??>
import java.text.ParseException;
import static redora.db.SQLParameter.yyyyMMdd;
import static redora.db.SQLParameter.yyyyMMddHHMMSS;
import java.util.logging.Level;
import java.util.logging.Logger;
import ${object.@package}.model.*;
import ${object.@package}.model.fields.${object.@name}Fields;
import static redora.api.fetch.Page.ALL_TABLE;
import static redora.api.fetch.Page.ALL_LIST;
<#if object.description[0]??>
/**
* ${object.description}
* @author Redora (www.redora.net)
*/
public class ${object.@name}Base implements <#if object.sorted == "true">SortedPersistable<#if object.interface[0]??>, ${object.interface} {
private static final transient Logger l = Logger.getLogger("${object.@package}.model.${object.@name}Base");
/** How deep should the isDirty() check go. @see #isDirty() */
public static final int MAX_DIRTY_LEVEL = 7;
public Long id;
@Override
public Long getId() {
return id;
}
public void setId(@org.jetbrains.annotations.NotNull Long id) {
if (this.id != null) throw new IllegalArgumentException("It is not allowed to modify the id");
this.id = id;
}
public Date creationDate;
public Date getCreationDate() {
assert fetchScope != redora.api.fetch.Scope.List : "This object is fetched as Scope.List. Fetch the object with Table or Form scope instead.";
return this.creationDate;
}
public Date updateDate;
public Date getUpdateDate() {
assert fetchScope != redora.api.fetch.Scope.List : "This object is fetched as Scope.List. Fetch the object with Table or Form scope instead.";
return this.updateDate;
}
<#list doc["/object/attributes/enum[@scope='local']"] as att>
<#if att.description[0]??>
/** ${att.description} */
public enum ${att.@class} {
<#list att.element as value>
<#if value.@description[0]??>
/** ${value.@description} */
${value.@name}<#if value_has_next>,<#else>;
/** @return Null, or the result of valueOf() */
public static ${att.@class} valueOfNullSafe(String value) {
if (value != null) {
return valueOf(value);
}
return null;
}
}
<#list object.formScope?children as att><#if att?node_type == "element">
<#if att.@notnull == "true" && att.@default[0]??>@org.jetbrains.annotations.NotNull
public ${att.@className} ${att.@fieldName};
<#if att?node_name == "object">
/** @return true if ${att.@fieldName} does not need to be (lazy) fetched from DB anymore. */
public boolean ${att.@fieldName}IsRetrieved() {
return ${att.@fieldName} != null || ${att.@fieldName}Id == null || ${att.@fieldName}Id.equals(-1L);
}
<#list object.attributes.set as att>
protected final ${att.@className} ${att.@fieldName} = new Persistable<#if att.@multiplicity == "n-to-m" && (att.@sorted == "both" || att.@sorted == "them") || att.@sorted == "true">SortedArrayList<${att.@class}>(<#if att.@multiplicity == "n-to-m" && (att.@sorted == "both" || att.@sorted == "them")>true<#elseif att.@sorted == "true">false);
/** @return true if ${att.@fieldName} does not need to be (lazy) fetched from DB anymore. */
public boolean ${att.@fieldName}IsRetrieved() {
return ${att.@fieldName}.isRetrieved();
}
public final Map<${object.@name}Fields, Object> dirty = new EnumMap<${object.@name}Fields, Object>(${object.@name}Fields.class);
public boolean isNew;
/** How is this object retrieved. By default (if for example the object is new) it's scope is assumed as Form. */
public redora.api.fetch.Scope fetchScope;
/**
* This method will set default values for:
<#list doc["/object/attributes/*[@default]"] as att>
* ${att.@fieldName} - ${att.@default};
*/
protected ${object.@name}Base() {
super();
<#list doc["/object/attributes/*[@default]"] as att>
<#if att?node_name == "boolean">
${att.@fieldName} = Boolean.${att.@default?upper_case};
<#elseif att?node_name == "string">
${att.@fieldName} = "${att.@default}";
<#elseif att?node_name == "integer" || att?node_name == "long" || att?node_name == "double">
${att.@fieldName} = ${att.@default}<#if att?node_name == "long">L;
<#elseif att?node_name == "enum">
${att.@fieldName} = ${att.@className}.${att.@default};
<#else>
error - undefined default ${att?node_name}
isNew = true;
fetchScope = redora.api.fetch.Scope.Form;
<#list object.attributes.set as att>
${att.@fieldName}.reset();
}
/**
* Initializes ${object.@name} using a record in a ResultSet.
* @param rs (Mandatory) ResultSet object using the field set defined in ${object.@name}SQLBase pointing to the record you want to serialize.
* @param offset (Mandatory) Usually 0, but if the field set is more then this object's field set you must set the offset.
* @param scope (Mandatory) The scope of the executed query, like Scope.Table of Scope.Form.
*/
public ${object.@name}Base(@org.jetbrains.annotations.NotNull ResultSet rs, int offset
, @org.jetbrains.annotations.NotNull redora.api.fetch.Scope scope) throws CopyException {
super();
${object.@name}Util.copy(rs, offset, scope, this);
isNew = false;
dirty.clear();
}
<#list object.formScope?children as att>
<#if att.description[0]??>
/**
* ${att.description}
*/
public void set${att.@fieldName?cap_first}(@org.jetbrains.annotations.<#if att.@notnull == "true">NotNull<#else>Nullable ${att.@className} ${att.@fieldName}) <#if att.@lazy == "true" && att?node_name == "string">throws LazyException <#elseif att?node_name == "html">throws LazyException, FieldException{
assert fetchScope != redora.api.fetch.Scope.List : "Modification is not allowed, this object is fetched as Scope.List and cannot be persisted. Fetch the object with Table or Form scope instead.";
<#if att?node_name == "date" || att?node_name == "datetime">
String stripped = null;
//strip (nano) seconds - hours to ${att?node_name} level
if (${att.@fieldName} != null) {
stripped = yyyyMMdd<#if att?node_name == "datetime">HHMMSS.format(${att.@fieldName});
}
if ((this.${att.@fieldName} == null ? null : yyyyMMdd<#if att?node_name == "datetime">HHMMSS.format(this.${att.@fieldName})) != stripped) {
if (!dirty.containsKey(${object.@name}Fields.${att.@fieldName})) {
dirty.put(${object.@name}Fields.${att.@fieldName}, this.${att.@fieldName});
}
if (stripped == null) {
this.${att.@fieldName} = null;
} else {
try {
this.${att.@fieldName} = yyyyMMdd<#if att?node_name == "datetime">HHMMSS.parse(stripped);
} catch (ParseException e) {
l.log(Level.SEVERE, "Did not expect this would not parse to date " + stripped, e);
throw new RuntimeException("Did not expect this would not parse to date " + stripped, e);
}
}
}
}
<#elseif att?node_name == "object">
<#if att.@pigsear == "true">
assert !this.equals(${att.@fieldName}) : "Circular reference " + ${att.@fieldName};
if (!dirty.containsKey(${object.@name}Fields.${att.@fieldName}Id)) {
if (${att.@fieldName}Id == null ? ${att.@fieldName} != null : ${att.@fieldName} == null || !${att.@fieldName}Id.equals(${att.@fieldName}.getId())) {
dirty.put(${object.@name}Fields.${att.@fieldName}Id, this.${att.@fieldName}Id);
}
}
this.${att.@fieldName} = ${att.@fieldName};
if (this.${att.@fieldName} != null) {
this.${att.@fieldName}Id = ${att.@fieldName}.getId();
} else {
this.${att.@fieldName}Id = null;
}
}
<#elseif att?node_name == "html">
if (${att.@fieldName} != null) {
String _cleanHtml = HtmlSanitizer.clean("${att.@policy[0]!"antisamy.xml"}", ${att.@fieldName});
if (!_cleanHtml.equals(this.${att.@fieldName})) {
if (!dirty.containsKey(${object.@name}Fields.${att.@fieldName})) {
dirty.put(${object.@name}Fields.${att.@fieldName}, get${att.@fieldName?cap_first}());
}
this.${att.@fieldName} = _cleanHtml;
}
} else if (this.${att.@fieldName} != null) {
if (!dirty.containsKey(${object.@name}Fields.${att.@fieldName})) {
dirty.put(${object.@name}Fields.${att.@fieldName}, this.${att.@fieldName});
}
this.${att.@fieldName} = null;
}
}
<#elseif att?node_type == "element">
if ((${att.@fieldName} == null ? this.${att.@fieldName} != null : !${att.@fieldName}.equals(this.${att.@fieldName}))
&& !dirty.containsKey(${object.@name}Fields.${att.@fieldName})) {
dirty.put(${object.@name}Fields.${att.@fieldName}, this.${att.@fieldName});
}
this.${att.@fieldName} = ${att.@fieldName};
}
<#if att.description[0]??>
/**
* ${att.description}
*/
public ${att.@className} get${att.@fieldName?cap_first}() <#if att.@lazy == "true">throws LazyException {
<#if att.@list == "false">
assert fetchScope != redora.api.fetch.Scope.List : "This object is fetched as Scope.List. Fetch the object with Table or Form scope instead.";
<#if att.@lazy == "true">
<#if att?node_name == "object">
if (${att.@fieldName}Id != null && ${att.@fieldName} == null) {
<#else>
if (fetchScope == redora.api.fetch.Scope.Table) {
fetchLazy();
}
return ${att.@fieldName};
}
<#list object.attributes.set as att>
/**
<#if att.description[0]??>
* ${att.description}
<#if att.@sorted == "true">
*
* This relationship is sortable, use the moveTo() function like get${att.@fieldName?cap_first}().moveTo(object, position);
*
* If you wish to add a ${att.@class} to this list, do something like: get${att.@class}s().add(${att.@class});.
* All the Collection methods like add, remove, addAll and removeAll are supported.
* When you add or update ${att.@plural} to this set, they will be persisted together with ${object.@name}.
* @return Empty or filled list.
*/
@org.jetbrains.annotations.NotNull
public ${att.@className} get${att.@fieldName?cap_first}() throws QueryException {
if (!${att.@fieldName}.isRetrieved()) {
${att.@class}Service service = null;
try {
service = ServiceFactory.${att.@class?uncap_first}Service();
${att.@fieldName}.addAll(service.finder(${object.@package}.sql.base.${att.@class}SQLBase.DefaultFinder.FindBy${att.@myName?cap_first}Id, id, fetchScope == redora.api.fetch.Scope.List ? ALL_LIST : ALL_TABLE));
} catch (RedoraException e) {
throw new QueryException("Failed to retrieve ${att.@fieldName} for " + this.toString(), e);
} finally {
ServiceFactory.close(service);
}
${att.@fieldName}.reset();
}
return ${att.@fieldName};
}
/**
* Checks if any of the attributes have changed. Also the related children and objects are checked.
* If you want to avoid the related object dirty check, use isDirty(${object.@name}.MAX_DIRTY_LEVEL) instead.
* @return true if any of the attributes of ${object.@name} have changed
*/
public boolean isDirty() {
return isDirty(new HashSet());
}
/**
* {@inheritDoc}
* @see #isDirty()
* @param ignore (Optional) List of already dirty checked objects to avoid circular checking.
* @return true is somewhere something has changed
*/
@Override
public boolean isDirty(@org.jetbrains.annotations.NotNull Set ignore) {
if (!dirty.isEmpty()) {
return true;
}
<#if doc["/object/attributes/set"][0]?? || doc["/object/attributes/object"][0]??>
try {
<#list doc["/object/attributes/set"] as att>
if (${att.@fieldName}IsRetrieved() && get${att.@fieldName?cap_first}().isDirty(ignore)) {
return true;
}
<#list doc["/object/attributes/object"] as att>
if (${att.@fieldName}IsRetrieved() && get${att.@fieldName?cap_first}() != null && ignore.add(get${att.@fieldName?cap_first}()) && get${att.@fieldName?cap_first}().isDirty(ignore)) {
return true;
}
} catch (RedoraException e) {
l.log(Level.SEVERE, "This exception can't happen because i should not perform any kind of DB related activities", e);
}
return false;
}
@Override
/** Checks primarily on Id, if there is no Id, it will try hashCode. */
public boolean equals(Object that) {
if (this == that)
return true;
if (that instanceof ${object.@name})
return equals((${object.@name})that);
return false;
}
/** Checks primarily on Id, if there is no Id, it will try hashCode. */
public boolean equals(${object.@name} that) {
if (id != null)
return that.id != null && id.longValue() == that.id.longValue();
else
return that.id == null && hashCode() == that.hashCode();
}
/**
* The hashCode is computed on the Id which is as fast as it can get. If there is
* no Id (new object), the hash code is calculated on all the other fields.
* @return the hash code of Id, or, when null, a hash code created by all the other fields.
*/
@Override
public int hashCode() {
if (id != null) {
return id.hashCode();
}
return new HashCodeBuilder(<#if object.@sequence?number % 2 == 0>${object.@sequence?number + 97}<#else>${object.@sequence}, 37)
<#list object.formScope?children as att>
<#if att?node_name != "object">
.append(${att.@fieldName})
.toHashCode();
}
/**
* Provides info from following fields:
<#if object.listScope[0]??>
<#list object.listScope?children as att>
<#if att?node_name != "object">
* ${att.@fieldName}
* and id
*/
@Override
public String toString() {
StringBuilder retVal = new StringBuilder();
<#if object.listScope[0]??>
<#list object.listScope?children as att>
<#if att?node_name != "object">
retVal.append(${att.@fieldName}).append(" ");
retVal.append('(').append(id).append(')');
return retVal.toString();
}
/**
* Creates a new ${object.@name} with all the same values, also related children are cloned.
* When you persist, only the Id('s) will differ.
*
* Parent objects, will be copied, 1-to-n children will be cloned, n-to-m children will
* be copied. In fact, everything will be copied, only children will be cloned.
*
* The clone method is somewhat potent because it also clones related objects.
* It however restrains itself by cloning until the MAX_DIRTY_LEVEL and direct
* pigsears (1-to-n and n-to-m) are resolved. Indirect pigsears (relations that
* use an intermediate object) are not resolved and can lead to runaway cloning.
*
* id, creationDate and updateDate are not copied.
* @see #MAX_DIRTY_LEVEL
* @return the cloned ${object.@name} or null when there was a LazyException.
*/
@Override
@SuppressWarnings({"CloneDoesntCallSuperClone"})
public ${object.@name} clone() {
return clone(1);
}
/**
* Creates a new ${object.@name} with all the same values, also related children are cloned.
* When you persist, only the Id('s) will differ.
* This method is used primarily to implement the clone() method.
* @see #clone()
* @param depth The depth of the cloning process into a string of relations.
* @return the cloned ${object.@name} or null when there was a LazyException.
*/
@Override
public ${object.@name} clone(int depth) {
${object.@name} retVal = new ${object.@name}();
retVal.cloneMasterId = getId();
try {
<#list object.attributes?children as att>
<#if att?node_type == "element">
<#if att?node_name == "set">
<#if att.@multiplicity == "n-to-m">
retVal.get${att.@fieldName?cap_first}().addAll(get${att.@fieldName?cap_first}());
<#else>
if (depth < MAX_DIRTY_LEVEL) {
retVal.get${att.@fieldName?cap_first}().addAll(get${att.@fieldName?cap_first}().clone(depth + 1));
}
<#elseif att?node_name == "object">
//Only copy object relations on the first level, if you need more, then override this behavior in ${object.@name}.java.
if (depth == 1 && get${att.@fieldName?cap_first}() != null) {
retVal.set${att.@fieldName?cap_first}(get${att.@fieldName?cap_first}().clone(MAX_DIRTY_LEVEL));
}
<#elseif (att?node_name != "long" || !att.@parentClass[0]??)>
retVal.set${att.@fieldName?cap_first}(get${att.@fieldName?cap_first}());
} catch (Exception e) {
l.log(Level.SEVERE, "Failed to clone this ${object.@name} " + getId(), e);
retVal = null;
}
return retVal;
}
/** When cloned, the master's id is kept here. This id is not persisted.*/
public Long cloneMasterId;
<#if object.hasLazy == "true">
protected void fetchLazy() throws LazyException {
//Set fetchScope at the beginning, otherwise you might get an infinite loop with get/set thinking it is still lazy
fetchScope = redora.api.fetch.Scope.Form;
try {
<#if object.lazyScope[0]??>
if (!isNew) {
${object.@name}Service service = ServiceFactory.${object.@name?uncap_first}Service();
Map _lazy = service.fetchLazy(id);
ServiceFactory.close(service);
<#list doc["/object/lazyScope/*"] as att>
<#if att?node_type == "element">
if (_lazy.get(${object.@name}Fields.${att.@fieldName}.name()) != null) {
${att.@fieldName} = (${att.@className})_lazy.get(${object.@name}Fields.${att.@fieldName}.name());
}
}
<#list doc["/object/attributes/object[@lazy='true']"] as att>
if (${att.@fieldName}Id != null) {
${att.@className}Service service = ServiceFactory.${att.@className?uncap_first}Service();
try {
${att.@fieldName} = service.findById(${att.@fieldName}Id, redora.api.fetch.Scope.Table);
} catch (RedoraException e) {
throw new LazyException("Can retrieve ${att.@fieldName} " + ${att.@fieldName}Id, e);
} finally {
ServiceFactory.close(service);
}
}
} catch (ConnectException e) {
throw new LazyException("Failed to get a connection to retrieve lazy fetched attributes for ${object.@name} " + id, e);
}
}
<#if object.sorted == "true">
@Override
public int compareTo(Object o) {
return getSortOrder().compareTo(((${object.@name})o).getSortOrder());
}
}