前言
对于简单的实体操作,基本代码都是一样的,作者根据前两篇文章介绍的方式,自己编写了一个度量单位实体的代码,并以这个代码为模板编写python脚本自动生成前后端代码脚本,大大提高了Thingsboard实体开发的效率
python脚本
# base on unit entity
import os
entity_type = 'LOT_ITEM'
# home_path = 'D:\\code\\thingsboard\\'
home_path = 'D:\\projects\\thingsboard\\'
entity_name_high = 'LotItem'
entity_name_low = 'lotItem'
#back
entity_folder_name = 'lotitem'
table_name = 'lotitem'
# front g
front_home = home_path + r'\ui-ngx'
model_folder = front_home +r'\src\app\shared\models'
model_id_folder = model_folder +r'\id'
model_name ='lot-item'
page_folder = front_home + r'\src\app\modules\home\pages'
http_folder = front_home + r'\src\app\core\http'
entity_autocomplete =front_home + r'\src\app\shared\components\entity\entity-autocomplete.component.ts'
def print_hi(name):
# Use a breakpoint in the code line below to debug your script.
print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint.
def get_entity_type_file():
return home_path + r'common\data\src\main\java\org\thingsboard\server\common\data\EntityType.java'
def get_resource_file():
return home_path + r'application\src\main\java\org\thingsboard\server\service\security\permission\Resource.java'
def get_entity_id_folder():
return home_path + r'common\data\src\main\java\org\thingsboard\server\common\data\id'
def get_entity_folder():
return home_path + r'common\data\src\main\java\org\thingsboard\server\common\data'
def get_entity_default_tenant_profile_configuration_file():
return home_path + r'common\data\src\main\java\org\thingsboard\server\common\data\tenant\profile\DefaultTenantProfileConfiguration.java'
def get_entity_model_constants_file():
return home_path + r'dao\src\main\java\org\thingsboard\server\dao\model\ModelConstants.java'
def get_entity_dao_service_folder():
return home_path + r'common\dao-api\src\main\java\org\thingsboard\server\dao\unit'
def get_entity_model_folder():
return home_path + r'dao\src\main\java\org\thingsboard\server\dao\model\sql'
def get_entity_repository_folder():
return home_path + r'dao\src\main\java\org\thingsboard\server\dao\sql'
def get_entity_dao_folder():
return home_path + r'dao\src\main\java\org\thingsboard\server\dao'
def get_entity_controller_folder():
return home_path + r'application\src\main\java\org\thingsboard\server\controller'
def get_entity_id_file():
return home_path + r'common\data\src\main\java\org\thingsboard\server\common\data\id\EntityIdFactory.java'
def get_tenant_admin_permissions_file():
return home_path + r'application\src\main\java\org\thingsboard\server\service\security\permission\TenantAdminPermissions.java'
def get_access_validator_file():
return home_path + r'application\src\main\java\org\thingsboard\server\service\security\AccessValidator.java'
def get_base_entity_service_file():
return home_path + r'dao\src\main\java\org\thingsboard\server\dao\entity\BaseEntityService.java'
def replace_str(folder_str, file_str):
lines = []
with open(folder_str + file_str) as f:
for line in f:
# new_line = line
# if line.find('Unit') != -1:
# new_line = line.replace('Unit', entity_name_high)
# lines.append(new_line)
# elif line.find('unit') != -1:
# new_line = line.replace('unit', entity_name_low)
# lines.append(new_line)
# elif line.find('UNIT') != -1:
# new_line = line.replace('UNIT', entity_type)
# lines.append(new_line)
# else:
# lines.append(line)
new_line = line.replace('Unit', entity_name_high).replace('unit', entity_name_low).replace('UNIT',
entity_type)
lines.append(new_line)
return lines
def g_file(lines, file_str):
with open(file_str, 'w') as f:
for n in lines:
f.write(n)
def g_foler(path):
isExists = os.path.exists(path)
if not isExists:
os.makedirs(path)
return True
else:
return False
def m_entity_type():
lines = []
with open(get_entity_type_file(), 'r') as f:
for line in f:
if line.find('NULL_ENTITY,') == -1:
lines.append(line)
else:
lines.append(line + entity_type + ',')
with open(get_entity_type_file(), 'w') as f:
for n in lines:
f.write(n)
def m_resource():
lines = []
with open(get_resource_file(), 'r') as f:
for line in f:
if line.find('// g-code') != -1:
lines.append(line)
lines.append(' ' + entity_type + '(EntityType.' + entity_type + '),\n')
else:
lines.append(line)
with open(get_resource_file(), 'w') as f:
for n in lines:
f.write(n)
def g_entity_id():
lines = replace_str(get_entity_id_folder(), r'\UnitId.java')
g_file(lines, get_entity_id_folder() + '\\' + entity_name_high + 'Id.java')
def g_entity():
lines = replace_str(get_entity_folder(), r'\Unit.java')
g_file(lines, get_entity_id_folder() + '\\' + entity_name_high + '.java')
def m_default_tenant_profile_configuration():
lines = []
with open(get_entity_default_tenant_profile_configuration_file()) as f:
for line in f:
if line.find('// g-code') != -1:
lines.append(line)
new_line = ' private long max' + entity_name_high + 's;\n'
lines.append(new_line)
else:
lines.append(line)
with open(get_entity_default_tenant_profile_configuration_file(), 'w') as f:
for n in lines:
f.write(n)
def m_model_constants():
lines = []
with open(get_entity_model_constants_file()) as f:
for line in f:
if line.find('// g-code') != -1:
lines.append(line)
new_line = ' /**\n'
lines.append(new_line)
new_line = ' * Cassandra unit constants. add by william g-code\n'
lines.append(new_line)
new_line = ' */\n'
lines.append(new_line)
new_line = ' public static final String ' + entity_type + '_COLUMN_NAME = "' + table_name + '";\n'
lines.append(new_line)
new_line = ' public static final String ' + entity_type + '_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;\n'
lines.append(new_line)
new_line = ' public static final String ' + entity_type + '_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY;\n'
lines.append(new_line)
new_line = ' public static final String ' + entity_type + '_NAME_PROPERTY = "name";\n'
lines.append(new_line)
new_line = ' public static final String ' + entity_type + '_LABEL_PROPERTY = "label"\n'
lines.append(new_line)
new_line = ' public static final String ' + entity_type + '_TYPE_PROPERTY = "type";\n'
lines.append(new_line)
new_line = ' public static final String ' + entity_type + '_STATUS_PROPERTY = "status";\n'
lines.append(new_line)
else:
lines.append(line)
with open(get_entity_model_constants_file(), 'w') as f:
for n in lines:
f.write(n)
def g_entity_dao_service():
lines = replace_str(get_entity_dao_service_folder(), r'\UnitService.java')
g_file(lines, get_entity_dao_service_folder() + '\\' + entity_name_high + 'Service.java')
def g_entity_model():
lines = replace_str(get_entity_model_folder(), r'\UnitEntity.java')
g_file(lines, get_entity_model_folder() + '\\' + entity_name_high + 'Entity.java')
def g_entity_repository():
lines = replace_str(get_entity_repository_folder(), r'\unit\UnitRepository.java')
g_foler(get_entity_repository_folder() + '\\' + entity_folder_name)
g_file(lines,
get_entity_repository_folder() + '\\' + entity_folder_name + '\\' + entity_name_high + 'Repository.java')
def g_entity_dao():
lines = replace_str(get_entity_dao_folder(), r'\unit\UnitDao.java')
g_foler(get_entity_dao_folder() + '\\' + entity_folder_name)
g_file(lines, get_entity_dao_folder() + '\\' + entity_folder_name + '\\' + entity_name_high + 'Dao.java')
def g_entity_dao_service_impl():
lines = replace_str(get_entity_dao_folder(), r'\unit\UnitServiceImpl.java')
g_foler(get_entity_dao_folder() + '\\' + entity_folder_name)
g_file(lines, get_entity_dao_folder() + '\\' + entity_folder_name + '\\' + entity_name_high + 'ServiceImpl.java')
def g_entity_dao_jpa():
lines = replace_str(get_entity_repository_folder(), r'\unit\JpaUnitDao.java')
g_foler(get_entity_repository_folder() + '\\' + entity_folder_name)
g_file(lines, get_entity_repository_folder() + '\\' + entity_folder_name + '\\Jpa' + entity_name_high + 'Dao.java')
def g_entity_controller():
lines = replace_str(get_entity_controller_folder(), r'\UnitController.java')
g_file(lines, get_entity_controller_folder() + '\\' + entity_name_high + 'Controller.java')
def m_base_controller():
lines = []
with open(get_entity_controller_folder() + r'\BaseController.java') as f:
for line in f:
if line.find('// g-code-autowired') != -1:
lines.append(line)
new_line = ' @Autowired\n'
lines.append(new_line)
new_line = ' protected ' + entity_name_high + 'Service ' + entity_name_low + 'Service;\n'
lines.append(new_line)
elif line.find('// g-code-checkEntityId') != -1:
lines.append(line)
new_line = ' ' + entity_name_high + ' check' + entity_name_high + 'Id(' + entity_name_high + 'Id ' + entity_name_low + 'Id, Operation operation) throws ThingsboardException {\n'
lines.append(new_line)
new_line = ' try {\n'
lines.append(new_line)
new_line = ' validateId(' + entity_name_low + 'Id, "Incorrect ' + entity_name_low + 'Id " + ' + entity_name_low + 'Id);\n'
lines.append(new_line)
new_line = ' ' + entity_name_high + ' ' + entity_name_low + ' = ' + entity_name_low + 'Service.find' + entity_name_high + 'ById(getCurrentUser().getTenantId(), ' + entity_name_low + 'Id);\n'
lines.append(new_line)
new_line = ' checkNotNull(' + entity_name_low + ');\n'
lines.append(new_line)
new_line = ' accessControlService.checkPermission(getCurrentUser(), Resource.' + entity_type + ', operation, ' + entity_name_low + 'Id, ' + entity_name_low + ');\n'
lines.append(new_line)
new_line = ' return ' + entity_name_low + ';\n'
lines.append(new_line)
new_line = ' } catch (Exception e) {\n'
lines.append(new_line)
new_line = ' throw handleException(e, false);\n'
lines.append(new_line)
new_line = ' }\n'
lines.append(new_line)
new_line = ' }\n'
lines.append(new_line)
lines.append('\n')
else:
lines.append(line)
with open(get_entity_controller_folder() + r'\BaseController.java', 'w') as f:
for n in lines:
f.write(n)
def m_entity_id_factory():
lines = []
with open(get_entity_id_file()) as f:
for line in f:
if line.find('// g-code') != -1:
lines.append(line)
new_line = ' case ' + entity_type + ':\n'
lines.append(new_line)
new_line = ' return new ' + entity_name_high + 'Id(uuid);\n'
lines.append(new_line)
lines.append('\n')
else:
lines.append(line)
with open(get_entity_id_file(), 'w') as f:
for n in lines:
f.write(n)
def m_tenant_admin_permissions():
lines = []
with open(get_tenant_admin_permissions_file()) as f:
for line in f:
if line.find('// g-code-constructor') != -1:
lines.append(line)
new_line = ' put(Resource.' + entity_type + ', ' + entity_name_low + 'EntityPermissionChecker);\n'
lines.append(new_line)
lines.append('\n')
elif line.find('// g-code-permission-checker') != -1:
lines.append(line)
new_line = ' public static final PermissionChecker ' + entity_name_low + 'EntityPermissionChecker = new PermissionChecker() {\n'
lines.append(new_line)
new_line = ' @Override\n'
lines.append(new_line)
new_line = ' public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {\n'
lines.append(new_line)
new_line = ' if (!user.getTenantId().equals(entity.getTenantId())) {\n'
lines.append(new_line)
new_line = ' return false;\n'
lines.append(new_line)
new_line = ' }\n'
lines.append(new_line)
new_line = ' return true;\n'
lines.append(new_line)
new_line = ' }\n'
lines.append(new_line)
new_line = ' };\n'
lines.append(new_line)
lines.append('\n')
else:
lines.append(line)
with open(get_tenant_admin_permissions_file(), 'w') as f:
for n in lines:
f.write(n)
def m_access_validator():
lines = []
with open(get_access_validator_file()) as f:
for line in f:
if line.find('// g-code-autowired') != -1:
lines.append(line)
new_line = ' @Autowired\n'
lines.append(new_line)
new_line = ' protected ' + entity_name_high + 'Service ' + entity_name_low + 'Service;\n'
lines.append(new_line)
elif line.find('// g-code-validate') != -1:
lines.append(line)
new_line = ' private void validate' + entity_name_high + '(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) {\n'
lines.append(new_line)
new_line = ' if (currentUser.isSystemAdmin()) {\n'
lines.append(new_line)
new_line = ' callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));\n'
lines.append(new_line)
new_line = ' } else {\n'
lines.append(new_line)
new_line = ' ListenableFuture<' + entity_name_high + '> ' + entity_name_low + 'Future = ' + entity_name_low + 'Service.find' + entity_name_high + 'ByIdAsync(currentUser.getTenantId(), new ' + entity_name_high + 'Id(entityId.getId()));\n'
lines.append(new_line)
new_line = ' Futures.addCallback(' + entity_name_low + 'Future, getCallback(callback, ' + entity_name_low + ' -> {\n'
lines.append(new_line)
new_line = ' if (' + entity_name_low + ' == null) {\n'
lines.append(new_line)
new_line = ' return ValidationResult.entityNotFound("' + entity_name_high + ' with requested id wasn\'t found!");\n'
lines.append(new_line)
new_line = ' } else {\n'
lines.append(new_line)
new_line = ' try {\n'
lines.append(new_line)
new_line = ' accessControlService.checkPermission(currentUser, Resource.DEVICE, operation, entityId, ' + entity_name_low + ');\n'
lines.append(new_line)
new_line = ' } catch (ThingsboardException e) {\n'
lines.append(new_line)
new_line = ' return ValidationResult.accessDenied(e.getMessage());\n'
lines.append(new_line)
new_line = ' }\n'
lines.append(new_line)
new_line = ' return ValidationResult.ok(' + entity_name_low + ');\n'
lines.append(new_line)
new_line = ' }\n'
lines.append(new_line)
new_line = ' }), executor);\n'
lines.append(new_line)
new_line = ' }\n'
lines.append(new_line)
new_line = ' }\n'
lines.append(new_line)
lines.append('\n')
else:
lines.append(line)
with open(get_access_validator_file(), 'w') as f:
for n in lines:
f.write(n)
def m_base_entity_service():
lines = []
with open(get_base_entity_service_file()) as f:
for line in f:
if line.find('// g-code-autowired') != -1:
lines.append(line)
new_line = ' @Autowired\n'
lines.append(new_line)
new_line = ' protected ' + entity_name_high + 'Service ' + entity_name_low + 'Service;\n'
lines.append(new_line)
elif line.find('// g-code-fetch') != -1:
lines.append(line)
new_line = ' case ' + entity_type + ':\n'
lines.append(new_line)
new_line = ' hasName =' + entity_name_low + 'Service.find' + entity_name_high + 'ByIdAsync(tenantId, new ' + entity_name_high + 'Id(entityId.getId()));\n'
lines.append(new_line)
new_line = ' break;\n'
lines.append(new_line)
lines.append('\n')
else:
lines.append(line)
with open(get_base_entity_service_file(), 'w') as f:
for n in lines:
f.write(n)
def g_back():
# m_entity_type()
# g_entity_id()
# g_entity()
# m_default_tenant_profile_configuration()
# m_model_constants()
# g_entity_dao_service()
g_entity_model()
m_resource()
g_entity_repository()
g_entity_dao()
g_entity_dao_service_impl()
g_entity_dao_jpa()
g_entity_controller()
m_base_controller()
m_entity_id_factory()
m_tenant_admin_permissions()
m_access_validator()
m_base_entity_service()
def g_model_id():
lines = replace_str(model_id_folder, r'\unit-id.ts')
g_file(lines, model_id_folder + '\\' + model_name+'-id.ts')
def g_model():
lines =replace_str(model_folder, r'\unit.models.ts')
g_file(lines,model_folder+ '\\' +model_name+'.models.ts')
def m_front_entity_type():
lines = []
with open(model_folder+'\\entity-type.models.ts') as f:
for line in f:
if line.find('// g-code-type') != -1:
lines.append(line)
new_line = ' '+entity_type+' = \''+entity_type+'\',\n'
lines.append(new_line)
lines.append('\n')
elif line.find('// g-code-translation') != -1:
lines.append(line)
new_line = ' [\n'
lines.append(new_line)
new_line = ' EntityType.'+entity_type+',\n'
lines.append(new_line)
new_line = ' {\n'
lines.append(new_line)
new_line = ' type: \'entity.type-'+model_name+'\',\n'
lines.append(new_line)
new_line = ' typePlural: \'entity.type-'+model_name+'s'+'\',\n'
lines.append(new_line)
new_line = ' list: \'entity.list-of-'+model_name+'s'+'\',\n'
lines.append(new_line)
new_line = ' nameStartsWith: \'entity.'+model_name+'s'+'-name-starts-with'+'\',\n'
lines.append(new_line)
new_line = ' details: \''+model_name+'.details'+'\',\n'
lines.append(new_line)
new_line = ' add: \''+model_name+'.add'+'\',\n'
lines.append(new_line)
new_line = ' noEntities: \''+model_name+'.no-'+model_name+'s-text'+'\',\n'
lines.append(new_line)
new_line = ' search: \''+model_name+'.search'+'\',\n'
lines.append(new_line)
new_line = ' selectedEntities: \''+model_name+'.selected'+'\',\n'
lines.append(new_line)
new_line = ' }\n'
lines.append(new_line)
new_line = ' ],\n'
lines.append(new_line)
lines.append('\n')
elif line.find('// g-code-helplink') != -1:
lines.append(line)
new_line = ' [\n'
lines.append(new_line)
new_line = ' EntityType.'+entity_type+',\n'
lines.append(new_line)
new_line = ' {\n'
lines.append(new_line)
new_line = ' helpLinkId: \'otaUpdates\'\n'
lines.append(new_line)
new_line = ' }\n'
lines.append(new_line)
new_line = ' ],\n'
lines.append(new_line)
lines.append('\n')
else:
lines.append(line)
with open(model_folder+'\\entity-type.models.ts', 'w') as f:
for n in lines:
f.write(n)
def g_page_foler():
g_foler(page_folder + '\\' + model_name)
def g_pages():
lines = replace_str(page_folder, '\\unit\\units-table-config.resolver.ts')
g_file(lines, page_folder + '\\' + model_name + '\\' + model_name +'s-table-config.resolver.ts')
lines = replace_str(page_folder, '\\unit\\unit-tabs.component.ts')
g_file(lines, page_folder + '\\' + model_name + '\\' + model_name + '-tabs.component.ts')
lines = replace_str(page_folder, '\\unit\\unit-tabs.component.scss')
g_file(lines, page_folder + '\\' + model_name + '\\' + model_name + '-tabs.component.scss')
lines = replace_str(page_folder, '\\unit\\unit-tabs.component.html')
g_file(lines, page_folder + '\\' + model_name + '\\' + model_name + '-tabs.component.html')
lines = replace_str(page_folder, '\\unit\\unit-table-header.component.ts')
g_file(lines, page_folder + '\\' + model_name + '\\' + model_name + '-table-header.component.ts')
lines = replace_str(page_folder, '\\unit\\unit-table-header.component.scss')
g_file(lines, page_folder + '\\' + model_name + '\\' + model_name + '-table-header.component.scss')
lines = replace_str(page_folder, '\\unit\\unit-table-header.component.html')
g_file(lines, page_folder + '\\' + model_name + '\\' + model_name + '-table-header.component.html')
lines = replace_str(page_folder, '\\unit\\unit-routing.module.ts')
g_file(lines, page_folder + '\\' + model_name + '\\' + model_name + '-routing.module.ts')
lines = replace_str(page_folder, '\\unit\\unit.module.ts')
g_file(lines, page_folder + '\\' + model_name + '\\' + model_name + '.module.ts')
lines = replace_str(page_folder, '\\unit\\unit.component.ts')
g_file(lines, page_folder + '\\' + model_name + '\\' + model_name + '.component.ts')
lines = replace_str(page_folder, '\\unit\\unit.component.scss')
g_file(lines, page_folder + '\\' + model_name + '\\' + model_name + '.component.scss')
lines = replace_str(page_folder, '\\unit\\unit.component.html')
g_file(lines, page_folder + '\\' + model_name + '\\' + model_name + '.component.html')
def g_http_service():
lines = replace_str(http_folder, '\\unit.service.ts')
g_file(lines, http_folder + '\\' + model_name +'.service.ts')
def m_front_entity_autocomplete():
lines = []
with open(entity_autocomplete) as f:
for line in f:
if line.find('// g-code') != -1:
lines.append(line)
new_line = ' case EntityType.'+entity_type+'\':\n'
lines.append(new_line)
new_line = ' this.entityText = \''+entity_type+'\':\n'
lines.append(new_line)
new_line = ' case EntityType.'+entity_type+'\':\n'
lines.append(new_line)
new_line = ' case EntityType.'+entity_type+'\':\n'
lines.append(new_line)
new_line = ' case EntityType.'+entity_type+'\':\n'
lines.append(new_line)
lines.append('\n')
else:
lines.append(line)
with open(entity_autocomplete, 'w') as f:
for n in lines:
f.write(n)
def g_front():
g_model_id()
g_model()
m_front_entity_type()
g_page_foler()
g_pages()
g_http_service()
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
print_hi('PyCharm')
# g_back()
g_front()
# See PyCharm help at https://www.jetbrains.com/help/pycharm/
说明
此脚本是基于以开发好的unit实体对象为模板,进行开发的,只适用于单表操作的简单实体,如果多表操作可以在这个脚本生成的代码基础上进行修改。