logplus/Workflow/WFEngine/ObjectModel/ObjectModelBase/include/PaiObject.h
2026-01-16 17:18:41 +08:00

804 lines
26 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file PaiObject.h
* @brief Pai数据基类定义
* @date 2011-6-20
*/
#ifndef PAI_FRAME_IOBJECTMODEL_PAIOBJECT_H
#define PAI_FRAME_IOBJECTMODEL_PAIOBJECT_H
#include <QUuid>
#include <QList>
#include <QDataStream>
#include <QVariant>
// #include "ObjectModelService.h"
// #include "PaiObjectEventAgent.h"
#include "Property.h"
#include "PaiTypes.h"
#include "Turtle.h"
/**
* @brief 创建一个对象
* @param[in] className 对象名称
* @param[in] uid 对象id
*/
#define DECLARE_PAI_OBJECT(className, uid) \
static pai::objectmodel::PaiObject* CreateInstance() \
{ \
return new className(); \
} \
static const char* GetTypeIDString() \
{ \
return uid; \
} \
virtual QUuid GetTypeID() const \
{ \
return QUuid(uid); \
}
/**
* @brief 注册一个对象
* @param[in] className 对象名称
*/
#define IMPLEMENT_PAI_OBJECT(className) \
namespace pai \
{ \
namespace objectmodel \
{ \
class regist##className \
{ \
public:regist##className() \
{ \
GetObjectModelService()->Register(QUuid(className::GetTypeIDString()), className::CreateInstance); \
} \
}; \
} \
} \
pai::objectmodel::regist##className g_##className##_creator;
class QMutex;
namespace pai
{
namespace objectmodel
{
/**
* @class PaiObject
* @brief The base class for all object model
* @note 在所有获得子对象的函数接口中,
* 凡是函数名是针对Object的就会递归查找所有子项并且包括自己如:
* GetObject
* GetObjects
* GetObjectByName
* GetObjectByType
* 凡是函数名是针对Child或Children的就会只查找第一代子项不包括自己如:
* GetChild
* GetChildren
* GetChildrenCount
* GetChildByType
* RemoveChild
*/
class PAI_OBJECTMODEL_EXPORT PaiObject : public QObject
{
// friend class pai::objectmodel::IProjectManager;
public:
DECLARE_PAI_OBJECT(PaiObject,"{00000000-0000-0000-0000-000000000000}")
/**
* @enum OverrideFlag
* @brief 覆盖标识枚举变量
*/
enum OverrideFlag
{
Override, ///< 覆盖
NoOverride ///< 不覆盖
};
/**
* @enum Flag
* @brief 对象的各种标识
*/
enum Flag
{
VisibibleOnTree = 0x0001, ///< 该对象是否上树
Modified = 0x0002, ///< 用户是否在当前会话修改过该对象
// for the active status
ACTIVE = 0x0004, ///< 活跃的(项目,工区...)
INACTIVE = 0x0008, ///< 不活跃的(项目,工区...)
ALL = 0x000C, ///< 所有的(项目,工区...)
Loaded = 0x0010, ///< 该对象信息是否与数据库同步
DataLoaded = 0x0020, ///< 该对象数据是否已加载
ChildrenLoaded = 0x0040, ///< 是否已经加载子代该标志只能在SynDB函数中设置
IgnoreSyncDB = 0x0080, ///< 同步时是否忽略该对象(不是指的该对象是否允许刷新)
Syncabled = 0x0100, ///< 该节点是否可同步(该对象是否允许刷新)
Closed = 0x0200, ///< 该对象是否处于关闭状态
Deleting = 0x0400, ///< 该对象是否正在删除过程中
Deletable = 0x0800, ///< 该对象是否可以被删除(指从数据树删除)
DataModified = 0x1002, ///< 用户是否在当前会话修改过该对象的数据
Renameable = 0x2000, ///< 此对象是否可以重命名
ShadowNode = 0x4000 ///< 是否为影子节点即删除时不用去判断其是否lock
};
/**
* @enum ExistFlag
* @brief 存在的各种情况标识,即将废除
*/
enum ExistFlag
{
EXIST_DBN_HDFSY = -3, ///< 数据库不存在HDFS存在
EXIST_DBY_HDFSN = -2, ///< 数据库存在HDFS不存在
EXIST_DB_ERROR = -1, ///< 数据库出错
EXIST_DBN_HDFSN = 0, ///< 数据库和HDFS都不存在
EXIST_DBY_HDFSY = 1 ///< 数据库和HDFS都存在
};
/**
* @enum SortKeyFlag
* @brief 排序关键字
*/
enum SortKeyFlag
{
Sort_Key_Null = 0, ///< 没有排序关键字
Sort_By_Name, ///< 名称,标题等
Sort_By_CreateTime ///< 创建时间
};
/**
* @enum MountTree
* @brief 挂载数据树上枚举类型
*/
enum MountTree
{
MountOnTree = 0, ///< 数据挂载上树
MountNoTree ///< 数据不上树
};
/**
* @brief 构造函数
* @param[in] pParent 父对象句柄
*/
PaiObject(PaiObject* pParent = NULL);
/**
* @brief 虚析构函数
*/
virtual ~PaiObject();
/**
* @brief 自我删除包括孩子在内
*/
virtual void Delete();
/**
* @brief 为对象设置ID
* @param[in] id 需要设置的ID信息
*/
void SetID(const QUuid & id);
/**
* @brief 获取对象的ID
* @return 对象ID
*/
QUuid GetID() const;
/**
* @brief 设置DBID, 以后将会替换掉SetID
* @param[in] id 设置的DBID
*/
void SetDBID(const long long id);
/**
* @brief 获得对象DBID
* @return 对象的DBID
*/
long long GetDBID() const;
/**
* @brief 设置 owner ID即所有者的ID在工区以下节点值为所属工区 ID如果是工区则为所属项目ID如果是项目则为0
* @param[in] id ID
*/
void SetOwnerID(long long id);
/**
* @brief 获得 owner ID
* @return 返回owner ID
*/
long long GetOwnerID() const;
/**
* @brief 设置对象的名字标识
* @param[in] name 名字标识
*/
virtual void SetName(const QString & name);
/**
* @brief 获取对象对应的名字标识
* @return 名字标识
*
*/
virtual QString GetName() const;
/**
* @brief 得到该对象的物理路径 "/project/survey/name",即三段式路径,与数据树的路径无关
* @return 对象的物理路径
*/
virtual QString GetPhysicalFile() const;
/**
* @brief 设置对象的属性类型
* @param[in] type 对象的属性类型
*/
void SetType(const pai::ios::DATA_TYPE & type);
/**
* @brief 获取对象的属性类型
* @return 对象的属性类型
*/
pai::ios::DATA_TYPE GetType() const;
/**
* @brief 获取对象的类型名称
* @return 对象的类型名称
*/
QString GetTypeName() const;
/**
* @brief 得到包含所有祖先名字的全路径名字,各级之间的名字以/分割,数据树的真实路径
* @return 对象的全路径
*/
QString GetVisibleFile() const;
/**
* @brief 得到包含所有祖先名字的全路径名字,各级之间的名字以/分割,数据树的真实路径
* @return 对象的全路径
* TODO 仅供测井项目使用
*/
QString GetFullPathName() const{return GetVisibleFile();};
/**
* @brief 设置对象的Icon名称
* @param[in] iconName Icon名称
*/
void SetIconName(const QString & iconName);
/**
* @brief 获得对象的Icon名称
* @return 对象的Icon名称
*/
QString GetIconName() const;
/**
* @brief 获得大图标名,目前是在普通小图标名字的后面添加"_big"来组合成的,所也图标的真实名字必须和该规则一致
* 如小图标名project.png那么对应的大图标名必须是project_big.png
* @return 大图标名
*/
QString GetBigIconName() const;
/**
* @brief 获取对象的父对象
* @return 父对象
*/
PaiObject* GetParent() const;
void SetParent(PaiObject*PParent);
/**
* @brief 根据返回值的类型,返回相应类型的父指针,包括父类的父类, 但只返回最接近的一个。
* @return 父类指针在未找到时返回NULL
*/
template< typename T > T* GetForebear() const
{
PaiObject* pParent = GetParent();
while(pParent)
{
T* pT = dynamic_cast< T* > (pParent);
if(pT)
{
return pT;
}
pParent = pParent->GetParent();
}
return NULL;
}
/**
* @brief 根据类型ID返回相应类型的父指针包括父类的父类, 但只返回最接近的一个。
* @param[in] typeID 类型ID
* @return 父类指针在未找到时返回NULL
*/
PaiObject* GetForebear(const QUuid & typeID) const;
/**
* @brief 向该对象上添加字节点
* @param[in] pChild 子对象指针
* @param[in] mountTree 数据挂载到树上标识
* @return 是否添加成功
*/
virtual bool AddChild(PaiObject* pChild, MountTree mountTree = MountOnTree);
/**
* @brief 在iIndex之前插入一个孩子,插入后这个孩子指向了iIndex
* @param[in] index 插入的索引
* @param[in] pChild 待插入的孩子
* @return 是否插入成功
*/
virtual bool InsertChild(int index, PaiObject *pChild);
/**
* @brief 删除孩子节点
* @param[in] pChild 孩子节点指针
* @param[in] deleteChild 是否将孩子节点移除
* @return 是否删除成功
*/
virtual bool RemoveChild(PaiObject *pChild, bool deleteChild = false);
/**
* @brief 获得对象的所有孩子节点
* @param[in,out] children 孩子节点列表
*/
void GetChildren(QList< PaiObject* > & children) const;
/**
* @brief 获得该对象孩子节点数目
* @return 孩子节点数目
*/
int GetChildrenCount();
/**
* @brief 判断对象是否有孩子节点
* @return 是否有孩子节点
*/
bool HasChildren();
/**
* @brief 在孩子中查找数据库ID为dbid的孩子只查找第一级
* @param[in] dbid 要查找的数据库ID
* @return 找到返回对象指针未找到返回NULL
*/
PaiObject* GetChild(const long long dbid) const;
/**
* @brief 根据id查找对应的对象
* @param[in] id 对象ID
* @return 查找到的对象指针
*/
PaiObject* GetObject(const QUuid & id) const;
/**
* @brief 通过孩子数据库ID查询对象
* @param[in] dbid 要查询对象的数据库ID
* @return 查找到的对象指针
*/
PaiObject* GetObject(const long long dbid) const;
/**
* @brief 根据孩子名称查找对象
* @param[in] name 孩子名称
* @return 查找到的对象指针
*/
PaiObject* GetObjectByName(const QString & name,int depth) const;
/**
* @brief 根据孩子名称查找对象
* @param[in] name 孩子名称
* @return 查找到的对象指针
*/
PaiObject* GetObjectByName(const QString & name) const;
/**
* @brief 根据孩子的名字和类型得到孩子的指针
* @param[in] name 欲查找孩子的名字
* @param[in] objectType 欲查找孩子的类型
* @return 查找到的对象指针
*/
PaiObject* GetObjectByName(const QString & name, const QUuid & objectType) const;
/**
* @brief 递归地找出第一个具有指定类型的孩子.
* @param[in] typeID 对象类型标志符
* @param[in] depth 递归深度默认值10000即全部搜索1搜索到自己的孩子 2搜索到孩子的孩子 ...一次类推
* @return 查找到的对象指针
*/
PaiObject* GetObjectByType(const QUuid & typeID, int depth = 10000) const;
/**
* @brief 找出第一个具有指定类型的孩子.(只差找第一级)
* @param[in] typeID 对象类型标志符
* @return 查找到的对象指针
*/
PaiObject* GetChildByType(const QUuid & typeID) const;
/**
* @brief 递归地找出所有具有指定类型的孩子.
* @param[in,out] children 返回的指定类型的所有孩子
* @param[in] typeID 对象类型标志符
* @param[in] depth 递归深度默认值10000即全部搜索1搜索到自己的孩子 2搜索到孩子的孩子 ...一次类推
*/
void GetObjectByType(QList< pai::objectmodel::PaiObject* > & children,
const QUuid & typeID,
int depth = 10000) const;
/**
* @brief 获得所有该对象包含的DBID为dbid的对象列表包括自己
* @param[in] dbid 要获得对象的DBID
* @return 获得的对象列表
*/
QList< PaiObject* > GetObjects(const long long dbid) const;
/**
* @brief 获得所有该对象包含的对象列表,包括自己
* @return 获得的对象列表
*/
QList< PaiObject* > GetObjects() const;
/**
* @brief 根据指定的相等条件获取满足条件的对像
* @param[in,out] children 返回的满足条件的对象集合
* @param[in] equalCondition 相等条件
*/
template< typename T >
void GetObjects(QList< pai::objectmodel::PaiObject* > & children,
const pai::EqualCondition< pai::objectmodel::PaiObject, T > & equalCondition)
{
foreach(PaiObject* pChild, m_children)
{
if(equalCondition(pChild))
{
children.append(pChild);
}
pChild->GetObjects(children, equalCondition);
}
};
/**
* @brief 是否拥有指定标志
* @param [in] flag 指定标志
* @return 是否拥有指定标志
*/
bool HasFlag(Flag flag) const;
/**
* @brief 是否存在指定权限
* @param[in] type 传入的权限类型
* @note 这里int传入的值是JIOService里EOperation中的枚举类型
* 目前由于有其他工程包含了paiObject.所以不能直接添加Jioservice中的枚举类型
* 暂时用整形表示传入的枚举类型,以后进行修改。
* @return 是否存在指定权限
*/
virtual bool HasPermissionFlag(int type) const;
/**
* @brief 该对象是否被修改
* @return 注意该函数会递归每个child只要有一个孩子被修改则返回真,如果本身以及所有孩子都未被修改则返回假
*/
bool HasModified() const;
/**
* @brief 该对象是否被修改了数据
* @return 是否被修改了数据
*/
bool HasDataModified() const;
/**
* @brief 设置同步时是否忽略该对象
* @param[in] ignore 是否忽略
*/
void SetIgnoreSyncDB(bool ignore);
/**
* @brief 设置是否为Shadow节点
* @param[in] shadow 是否为影子节点
*/
void SetShadowNode(bool shadow);
/**
* @brief 设置该节点是否有同步功能是否有Refresh菜单
* @param[in] enable 是否有同步功能
*/
void SetSyncabled(bool enable);
/**
* @brief 获得属性信息,目前个别类型的属性信息需要单独构建
* @return 属性信息
*/
virtual QString GetProperties();
/**
* @brief 写入数据库新建的过程如果已存在请用UpdateToDB
* @param[in,out] pErrorMessage 如果发生错误在将错误信息添进pErrorMessage
* @return 是否写入成功
*/
virtual bool Save(QString *pErrorMessage = NULL);
/**
* @brief 更新入数据库
* @param[in,out] pErrorMessage 如果发生错误在将错误信息添进pErrorMessage
* @return 是否更新成功
*/
virtual bool Update(QString *pErrorMessage = NULL);
/**
* @brief 写入数据库新建的过程如果已存在请用UpdateToDB
* @param[in,out] pErrorMessage 如果发生错误在将错误信息添进pErrorMessage
* @return 是否写入成功
*/
virtual bool SaveToDB(QString *pErrorMessage = NULL);
/**
* @brief 更新入数据库
* @param[in,out] pErrorMessage 如果发生错误在将错误信息添进pErrorMessage
* @return 是否更新成功
*/
virtual bool UpdateToDB(QString *pErrorMessage = NULL);
/**
* @brief 在数据库中将该对象置于活动或非活动状态
* @param[in] status 活跃或非活跃标志(PaiObject::ACTIVE / PaiObject::INACTIVE)
* @param[in,out] pErrorMessage 如果发生错误在将错误信息添进pErrorMessage
* @return 是否设置成功
*/
virtual bool EnableToDB(const int & status, QString *pErrorMessage = NULL);
/**
* @brief 重新加载数据不加载孩子会调用Load函数
* @return 是否加载成功
*/
bool Reload();
/**
* @brief 同步该对象,包括数据,包括自身的数据和孩子的数据
* @param[in] mode 同步方式
* @return 是否同步成功
*/
bool SyncDB(pai::SyncModes mode);
/**
* @brief 同步该对象的孩子,包括数据,但不包括自身的数据
* @param[in] recursion 是否同时同步所有子代
* @return 是否同步成功
*/
bool SyncChildren(bool recursion);
/**
* @brief 获得最近缓冲的属性信息
* @return 最近缓冲的属性信息
*/
QString GetBackupProperties() const;
/**
* @brief 得到已指定前缀加自然数命名的下一个孩子的名字
* @param[in] childNamePrefix 孩子名字的前缀
* @return 得到的孩子名称
*/
QString GetNextChildName(const QString & childNamePrefix);
/**
* @brief 设置是否会发出EventAgent信号
* @param[in] yes 为真时将发射EventAgent信号默认为真
*/
void SetEventEnabled(bool yes);
/**
* @brief 获取是否会发出EventAgent信号
* @return 是否会发出EventAgent信号
*/
bool IsEventEnabled();
/**
* @brief 获取是否是大数据对象
* @return 是否是大数据对象
*/
virtual bool IsBigDataObject() const;
/**
* @brief 将该对象显示为关闭状态
* @param[in,out] pErrorMessage 如果发生错误在将错误信息添进pErrorMessage
* @return 是否关闭成功
*/
bool CloseObject(QString *pErrorMessage = NULL);
/**
* @brief 将该对象显示为打开状态
* @return 是否打开成功
*/
bool OpenObject();
/**
* @brief 设置是否要展开显示子对象
* @param[in] expand 是否要展开显示子对象
*/
void SetExpand(bool expand);
/**
* @brief 获得时间戳,可以用来判断两个数据是否一致,或某数据是否需要更新
* @return 时间戳
*/
long long GetTimeStamp() const;
/**
* @brief 通过比较的类型,比较两个对象的大小
* @param[in] pSrc 比较对象
* @param[in] pDest 被比较对象
* @param[in] key 比较类型关键字
* @return 即 *pSrc - *pDest 的值
*/
static int SortDataCompare(PaiObject *pSrc, PaiObject *pDest, const SortKeyFlag key);
/**********************************************************
* 以下虚函数请务必在派生类中重新定义 *
* 否则可能出现数据不对的情况,当然不是全 *
* 部派生类都会调用到,但是定义后会更安全 *
**********************************************************/
/**
* @brief 对对象重命名
* @param[in] newName 新名称
* @param[in] override 如果新名称已经存在,是否进行覆盖的标识
*/
virtual void Rename(const QString & newName, OverrideFlag override = NoOverride);
/**
* @brief 删除该对系对应的资源数据库、HDFS...
* @param[in,out] pErrorMessage 如果发生错误在将错误信息添进pErrorMessage
* @return 是否删除成功
*/
virtual bool Erase(QString *pErrorMessage = NULL);
/**
* @brief 加载DBID为dbid的数据不加载孩子
* @param[in] dbid DBID
* @return 是否加载成功
*/
virtual bool Load(const long long dbid);
/**
* @brief 克隆参数对象
* @param[in] srcObject 源对象
* @note 派生类实现的时候,需掉在最后调用基类函数,不时所有的信息都会拷贝,请慎重使用该函数
*/
virtual void Clone(const PaiObject & srcObject);
/**
* @brief 尝试删除对象,如果没法删除将返回无法删除的原因
* @param[in,out] message 无法删除的原因只有当返回false时才有效
* @return 判断是否可以删除
*/
virtual bool TryDelete(QString & message);
/**
* @brief 添加获取对象占用内存大小的接口,供数据树内存查看工具调用
* @return 对象占用内存大小
*/
virtual int GetMemorySize();
/**
* @brief 获得要刷新的孩子列表
* @param[in,out] children 孩子列表
* @return 是否获得成功
*/
virtual bool GetSyncChildren(QList< PaiObject* > & children);
/**
* @brief 根据owner id获得owner下属于该类型所有的节点
* @param[in] ownerID 获得节点需要提供的宿主节点ID
* @param[in] ownerType 获得节点需要提供的宿主节点类型
* @return owner下属于该类型所有的节点
*/
virtual QList<PaiObject*> GetBrothers(long long ownerID, const QUuid & ownerType);
protected:
/**
* @brief 设置该对象是否拥有指定标志
* @param[in] flag 指定标志
* @param[in] enable 标识该标记是否拥有
*/
void SetFlagEnable(Flag flag, bool enable);
/**
* @brief 设置该对象是否被修改过
* @param[in] modified 是否被修改过
* @param[in] recursive 是否递归设置孩子的修改状态
*/
void SetModified(bool modified, bool recursive);
/**
* @brief 删除所有孩子并释放所有孩子的内存
*/
void ReleaseChildren();
/**
* @brief 获得所有该对象包含的对象,包括自己
* @param[in,out] objects 获得的对象指针
*/
void GetObjects(QList< PaiObject* > & objects) const;
/**
* @brief 获得节点排序的依据数据
* @param[in] key 排序的依据类型
* @return 排序比较的数据
*/
virtual QVariant GetSortData(const SortKeyFlag key) const;
/**
* @brief 获取对象的创建时间
* @return 对象的创建时间
*/
virtual long long GetCreateTime() const;
/**
* @brief 添加Load Loading 节点,只有当没有孩子时才会添加成功
* @param[in] mountTree 数据挂载到树上标识
* @return 是否添加成功
*/
bool AddLazyLoadChild(MountTree mountTree = MountOnTree);
/**
* @brief 删除 Lazy Loading孩子节点
* @return 是否删除成功
*/
bool RemoveLazyLoadChild();
/**
* @brief 同步孩子节点信息
* @param[in] children 需要同步的孩子节点列表
*/
void SyncChildren(QList< PaiObject* > & children);
/**
* @brief 设置对象的类型名称
* @param[in] typeName 对象的类型名称
*/
void SetTypeName(const QString & typeName);
/**
* @brief 同步刷新后的必要信息,即从最新的对象(latestObject)中,取出必要的信息同步本对象
* @param[in] latestObject 有最新数据的对象
* @note 必要的信息只包括“name”和"time stamp"
*/
void SyncRefreshMsg(const PaiObject & latestObject);
/**
* @brief 设置时间戳,可以用来判断两个数据是否一致,或某数据是否需要更新
* @param[in] timeStamp 时间戳
*/
void SetTimeStamp(const long long timeStamp);
/**
* @brief 添加自定的字符串比较函数,比较规则为当字符串不同时依据字符表顺序排序,
* 如果只是字母大小写不同,则大写字符排在小写字母之前
* @param[in] tag1 需要标记的字符串
* @param[in] tag2 需要标记的字符串
* @return 两字符串有个相异字符Ascii码值的差值整数表示后者在前负数表示前者在前0表示字符串无差异
*/
static int SpecialCompare(const QString & tag1, const QString & tag2);
public:
// static pai::objectmodel::PaiObjectEventAgent m_EventAgent; ///< 全局事件类
protected:
int m_flags; ///< 当前对象标识
QList< PaiObject* > m_children; ///< 记录孩子对象列表
QString m_properties; ///< 备份的属性信息
private:
PaiObject *m_pParent; ///< 对象的父节点
long long m_OwnerID; ///< 即所有者的ID在工区以下节点值为所属工区ID如果是工区则为所属项目ID如果是项目则为0, 无效:-1
QUuid m_id; ///< 对象ID
long long m_dbid; ///< 对象dbid
QString m_name; ///< 对象的名字
QString m_IconName; ///< 小图标
QString m_TypeName; ///< 用来表示类型名
long long m_TimeStamp; ///< 时间戳,用来记录对象的更新情况
bool m_EventEnabled; ///< 是否打开该对象与集中信号管理的连接
volatile bool m_SyncLockFlag; ///< 当由两个或多个线程在同时调用Sync函数的时候降低添加相同孩子的几率
pai::ios::DATA_TYPE m_type; ///< 数据类型
QMutex *m_pChildMutex; ///< 当添加或删除孩子时加锁
};
}
}
#endif ///< PAI_FRAME_IOBJECTMODEL_PAIOBJECT_H