📄 genericentity.java
字号:
/*
* $Id: GenericEntity.java,v 1.20 2004/01/28 01:04:51 jonesde Exp $
*
* Copyright (c) 2002 The Open For Business Project - www.ofbiz.org
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
* OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.ofbiz.entity;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Observable;
import java.util.ResourceBundle;
import java.util.TreeSet;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.LocalizedMap;
import org.ofbiz.base.util.UtilFormatOut;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.UtilXml;
import org.ofbiz.entity.jdbc.SqlJdbcUtil;
import org.ofbiz.entity.model.ModelEntity;
import org.ofbiz.entity.model.ModelField;
import org.ofbiz.entity.model.ModelFieldType;
import org.ofbiz.entity.util.ByteWrapper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Generic Entity Value Object - Handles persisntence for any defined entity.
* <p>Note that this class extends <code>Observable</code> to achieve change notification for
* <code>Observer</code>s. Whenever a field changes the name of the field will be passed to
* the <code>notifyObservers()</code> method, and through that to the <code>update()</code> method of each
* <code>Observer</code>.
*
*@author <a href="mailto:jonesde@ofbiz.org">David E. Jones</a>
*@author <a href="mailto:jaz@ofbiz.org">Andy Zeneski</a>
*@version $Revision: 1.20 $
*@since 2.0
*/
public class GenericEntity extends Observable implements Map, LocalizedMap, Serializable, Comparable, Cloneable {
public static final String module = GenericEntity.class.getName();
/** Name of the GenericDelegator, used to reget the GenericDelegator when deserialized */
protected String delegatorName = null;
/** Reference to an instance of GenericDelegator used to do some basic operations on this entity value. If null various methods in this class will fail. This is automatically set by the GenericDelegator for all GenericValue objects instantiated through it. You may set this manually for objects you instantiate manually, but it is optional. */
protected transient GenericDelegator internalDelegator = null;
/** Contains the fields for this entity. Note that this should always be a
* HashMap to allow for two things: non-synchronized reads (synchronized
* writes are done through synchronized setters) and being able to store
* null values. Null values are important because with them we can distinguish
* between desiring to set a value to null and desiring to not modify the
* current value on an update.
*/
protected Map fields;
/** Contains the entityName of this entity, necessary for efficiency when creating EJBs */
protected String entityName = null;
/** Contains the ModelEntity instance that represents the definition of this entity, not to be serialized */
protected transient ModelEntity modelEntity = null;
/** Denotes whether or not this entity has been modified, or is known to be out of sync with the persistent record */
protected boolean modified = false;
/** Used to specify whether or not this representation of the entity can be changed; generally cleared when this object comes from a cache */
protected boolean mutable = true;
/** This is an internal field used to specify that a value has come from a sync process and that the auto-stamps should not be over-written */
protected boolean isFromEntitySync = false;
/** Creates new GenericEntity */
public GenericEntity() {
this.entityName = null;
this.modelEntity = null;
this.fields = new HashMap();
}
/** Creates new GenericEntity */
public GenericEntity(ModelEntity modelEntity) {
if (modelEntity == null) throw new IllegalArgumentException("Cannont create a GenericEntity with a null modelEntity parameter");
this.modelEntity = modelEntity;
this.entityName = modelEntity.getEntityName();
this.fields = new HashMap();
}
/** Creates new GenericEntity from existing Map */
public GenericEntity(ModelEntity modelEntity, Map fields) {
if (modelEntity == null) throw new IllegalArgumentException("Cannont create a GenericEntity with a null modelEntity parameter");
this.modelEntity = modelEntity;
this.entityName = modelEntity.getEntityName();
this.fields = new HashMap();
setFields(fields);
}
/** Copy Constructor: Creates new GenericEntity from existing GenericEntity */
public GenericEntity(GenericEntity value) {
this.entityName = value.modelEntity.getEntityName();
this.modelEntity = value.modelEntity;
this.fields = (value.fields == null ? new HashMap() : new HashMap(value.fields));
this.delegatorName = value.delegatorName;
this.internalDelegator = value.internalDelegator;
}
public void refreshFromValue(GenericEntity newValue) throws GenericEntityException {
if (newValue == null) {
throw new GenericEntityException("Could not refresh value, new value not found for: " + this);
}
GenericPK thisPK = this.getPrimaryKey();
GenericPK newPK = newValue.getPrimaryKey();
if (!thisPK.equals(newPK)) {
throw new GenericEntityException("Could not refresh value, new value did not have the same primary key; this PK=" + thisPK + ", new value PK=" + newPK);
}
this.fields = newValue.fields;
this.setDelegator(newValue.getDelegator());
this.modified = false;
}
public boolean isModified() {
return this.modified;
}
public void synchronizedWithDatasource() {
this.modified = false;
}
public void removedFromDatasource() {
// seems kind of minimal, but should do for now...
this.modified = true;
}
public boolean isMutable() {
return this.mutable;
}
public void setImmutable() {
this.mutable = false;
}
/**
* @return Returns the isFromEntitySync.
*/
public boolean getIsFromEntitySync() {
return this.isFromEntitySync;
}
/**
* @param isFromEntitySync The isFromEntitySync to set.
*/
public void setIsFromEntitySync(boolean isFromEntitySync) {
this.isFromEntitySync = isFromEntitySync;
}
public String getEntityName() {
return entityName;
}
public ModelEntity getModelEntity() {
if (modelEntity == null) {
if (entityName != null) modelEntity = this.getDelegator().getModelEntity(entityName);
if (modelEntity == null) {
throw new IllegalStateException("[GenericEntity.getModelEntity] could not find modelEntity for entityName " + entityName);
}
}
return modelEntity;
}
/** Get the GenericDelegator instance that created this value object and that is repsonsible for it.
*@return GenericDelegator object
*/
public GenericDelegator getDelegator() {
if (internalDelegator == null) {
if (delegatorName != null) internalDelegator = GenericDelegator.getGenericDelegator(delegatorName);
if (internalDelegator == null) {
throw new IllegalStateException("[GenericEntity.getDelegator] could not find delegator with name " + delegatorName);
}
}
return internalDelegator;
}
/** Set the GenericDelegator instance that created this value object and that is repsonsible for it. */
public void setDelegator(GenericDelegator internalDelegator) {
if (internalDelegator == null) return;
this.delegatorName = internalDelegator.getDelegatorName();
this.internalDelegator = internalDelegator;
}
public Object get(String name) {
if (getModelEntity().getField(name) == null) {
throw new IllegalArgumentException("[GenericEntity.get] \"" + name + "\" is not a field of " + entityName);
}
return fields.get(name);
}
/** Returns true if the entity contains all of the primary key fields, but NO others. */
public boolean isPrimaryKey() {
TreeSet fieldKeys = new TreeSet(fields.keySet());
for (int i = 0; i < getModelEntity().getPksSize(); i++) {
if (!fieldKeys.contains(getModelEntity().getPk(i).getName())) return false;
fieldKeys.remove(getModelEntity().getPk(i).getName());
}
if (!fieldKeys.isEmpty()) return false;
return true;
}
/** Returns true if the entity contains all of the primary key fields. */
public boolean containsPrimaryKey() {
TreeSet fieldKeys = new TreeSet(fields.keySet());
for (int i = 0; i < getModelEntity().getPksSize(); i++) {
if (!fieldKeys.contains(getModelEntity().getPk(i).getName())) return false;
}
return true;
}
/** Sets the named field to the passed value, even if the value is null
* @param name The field name to set
* @param value The value to set
*/
public void set(String name, Object value) {
set(name, value, true);
}
/** Sets the named field to the passed value. If value is null, it is only
* set if the setIfNull parameter is true. This is useful because an update
* will only set values that are included in the HashMap and will store null
* values in the HashMap to the datastore. If a value is not in the HashMap,
* it will be left unmodified in the datastore.
* @param name The field name to set
* @param value The value to set
* @param setIfNull Specifies whether or not to set the value if it is null
*/
public synchronized Object set(String name, Object value, boolean setIfNull) {
if (!this.mutable) {
// comment this out to disable the mutable check
throw new IllegalStateException("This object has been flagged as immutable (unchangeable), probably because it came from an Entity Engine cache. Cannot set a value in an immutable entity object.");
}
ModelField modelField = getModelEntity().getField(name);
if (modelField == null) {
throw new IllegalArgumentException("[GenericEntity.set] \"" + name + "\" is not a field of " + entityName + ", must be one of: " + getModelEntity().fieldNameString());
}
if (value != null || setIfNull) {
if (value instanceof Boolean) {
// if this is a Boolean check to see if we should convert from an indicator or just leave as is
ModelFieldType type = null;
try {
type = getDelegator().getEntityFieldType(getModelEntity(), modelField.getType());
} catch (GenericEntityException e) {
Debug.logWarning(e, module);
}
if (type == null) throw new IllegalArgumentException("Type " + modelField.getType() + " not found");
try {
int fieldType = SqlJdbcUtil.getType(type.getJavaType());
if (fieldType != 9) {
value = ((Boolean) value).booleanValue() ? "Y" : "N";
}
} catch (GenericNotImplementedException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
Object old = fields.put(name, value);
modified = true;
this.setChanged();
this.notifyObservers(name);
return old;
} else {
return fields.get(name);
}
}
public void dangerousSetNoCheckButFast(ModelField modelField, Object value) {
if (modelField == null) throw new IllegalArgumentException("Cannot set field with a null modelField");
this.fields.put(modelField.getName(), value);
}
public Object dangerousGetNoCheckButFast(ModelField modelField) {
if (modelField == null) throw new IllegalArgumentException("Cannot get field with a null modelField");
return this.fields.get(modelField.getName());
}
/** Sets the named field to the passed value, converting the value from a String to the corrent type using <code>Type.valueOf()</code>
* @param name The field name to set
* @param value The String value to convert and set
*/
public void setString(String name, String value) {
if (value == null) {
set(name, null);
return;
}
ModelField field = getModelEntity().getField(name);
if (field == null) set(name, value); // this will get an error in the set() method...
ModelFieldType type = null;
try {
type = getDelegator().getEntityFieldType(getModelEntity(), field.getType());
} catch (GenericEntityException e) {
Debug.logWarning(e, module);
}
if (type == null) throw new IllegalArgumentException("Type " + field.getType() + " not found");
String fieldType = type.getJavaType();
try {
switch (SqlJdbcUtil.getType(fieldType)) {
case 1:
set(name, value);
break;
case 2:
set(name, java.sql.Timestamp.valueOf(value));
break;
case 3:
set(name, java.sql.Time.valueOf(value));
break;
case 4:
set(name, java.sql.Date.valueOf(value));
break;
case 5:
set(name, Integer.valueOf(value));
break;
case 6:
set(name, Long.valueOf(value));
break;
case 7:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -