com.liferay.object.service.impl.ObjectDefinitionLocalServiceImpl Maven / Gradle / Ivy
The newest version!
/**
* SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
* SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
*/
package com.liferay.object.service.impl;
import com.liferay.account.service.AccountEntryLocalService;
import com.liferay.account.service.AccountEntryOrganizationRelLocalService;
import com.liferay.asset.kernel.service.AssetEntryLocalService;
import com.liferay.fragment.cache.FragmentEntryLinkCache;
import com.liferay.fragment.model.FragmentEntryLink;
import com.liferay.layout.model.LayoutClassedModelUsage;
import com.liferay.layout.service.LayoutClassedModelUsageLocalService;
import com.liferay.object.constants.ObjectDefinitionConstants;
import com.liferay.object.constants.ObjectFieldConstants;
import com.liferay.object.constants.ObjectRelationshipConstants;
import com.liferay.object.definition.util.ObjectDefinitionThreadLocal;
import com.liferay.object.definition.util.ObjectDefinitionUtil;
import com.liferay.object.deployer.InactiveObjectDefinitionDeployer;
import com.liferay.object.deployer.ObjectDefinitionDeployer;
import com.liferay.object.exception.NoSuchObjectFieldException;
import com.liferay.object.exception.ObjectDefinitionAccountEntryRestrictedException;
import com.liferay.object.exception.ObjectDefinitionAccountEntryRestrictedObjectFieldIdException;
import com.liferay.object.exception.ObjectDefinitionActiveException;
import com.liferay.object.exception.ObjectDefinitionClassNameException;
import com.liferay.object.exception.ObjectDefinitionEnableCategorizationException;
import com.liferay.object.exception.ObjectDefinitionEnableCommentsException;
import com.liferay.object.exception.ObjectDefinitionEnableLocalizationException;
import com.liferay.object.exception.ObjectDefinitionEnableObjectEntryHistoryException;
import com.liferay.object.exception.ObjectDefinitionExternalReferenceCodeException;
import com.liferay.object.exception.ObjectDefinitionLabelException;
import com.liferay.object.exception.ObjectDefinitionModifiableException;
import com.liferay.object.exception.ObjectDefinitionNameException;
import com.liferay.object.exception.ObjectDefinitionPanelCategoryKeyException;
import com.liferay.object.exception.ObjectDefinitionPluralLabelException;
import com.liferay.object.exception.ObjectDefinitionPortletException;
import com.liferay.object.exception.ObjectDefinitionRootObjectDefinitionIdException;
import com.liferay.object.exception.ObjectDefinitionScopeException;
import com.liferay.object.exception.ObjectDefinitionStatusException;
import com.liferay.object.exception.ObjectDefinitionSystemException;
import com.liferay.object.exception.ObjectDefinitionVersionException;
import com.liferay.object.exception.ObjectFieldRelationshipTypeException;
import com.liferay.object.exception.ObjectRelationshipEdgeException;
import com.liferay.object.exception.RequiredObjectDefinitionException;
import com.liferay.object.field.util.ObjectFieldUtil;
import com.liferay.object.internal.dao.db.ObjectDBManagerUtil;
import com.liferay.object.internal.deployer.InactiveObjectDefinitionDeployerImpl;
import com.liferay.object.internal.deployer.ObjectDefinitionDeployerImpl;
import com.liferay.object.internal.security.permission.resource.util.ObjectDefinitionResourcePermissionUtil;
import com.liferay.object.model.ObjectAction;
import com.liferay.object.model.ObjectDefinition;
import com.liferay.object.model.ObjectEntry;
import com.liferay.object.model.ObjectEntryTable;
import com.liferay.object.model.ObjectField;
import com.liferay.object.model.ObjectFieldModel;
import com.liferay.object.model.ObjectFolder;
import com.liferay.object.model.ObjectRelationship;
import com.liferay.object.model.impl.ObjectDefinitionImpl;
import com.liferay.object.petra.sql.dsl.DynamicObjectDefinitionLocalizationTable;
import com.liferay.object.petra.sql.dsl.DynamicObjectDefinitionLocalizationTableFactory;
import com.liferay.object.petra.sql.dsl.DynamicObjectDefinitionTable;
import com.liferay.object.petra.sql.dsl.DynamicObjectDefinitionTableFactory;
import com.liferay.object.related.models.ObjectRelatedModelsProviderRegistrarHelper;
import com.liferay.object.scope.ObjectScopeProviderRegistry;
import com.liferay.object.service.ObjectActionLocalService;
import com.liferay.object.service.ObjectDefinitionLocalServiceUtil;
import com.liferay.object.service.ObjectEntryLocalService;
import com.liferay.object.service.ObjectEntryService;
import com.liferay.object.service.ObjectFieldLocalService;
import com.liferay.object.service.ObjectFolderItemLocalService;
import com.liferay.object.service.ObjectFolderLocalService;
import com.liferay.object.service.ObjectLayoutLocalService;
import com.liferay.object.service.ObjectLayoutTabLocalService;
import com.liferay.object.service.ObjectRelationshipLocalService;
import com.liferay.object.service.ObjectValidationRuleLocalService;
import com.liferay.object.service.ObjectViewLocalService;
import com.liferay.object.service.base.ObjectDefinitionLocalServiceBaseImpl;
import com.liferay.object.service.persistence.ObjectEntryPersistence;
import com.liferay.object.service.persistence.ObjectFieldPersistence;
import com.liferay.object.service.persistence.ObjectFolderPersistence;
import com.liferay.object.service.persistence.ObjectRelationshipPersistence;
import com.liferay.object.system.SystemObjectDefinitionManager;
import com.liferay.object.tree.Node;
import com.liferay.object.tree.ObjectDefinitionTreeFactory;
import com.liferay.object.tree.Tree;
import com.liferay.petra.lang.SafeCloseable;
import com.liferay.petra.sql.dsl.Column;
import com.liferay.petra.sql.dsl.Table;
import com.liferay.petra.string.StringBundler;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.aop.AopService;
import com.liferay.portal.kernel.cluster.ClusterExecutorUtil;
import com.liferay.portal.kernel.cluster.ClusterRequest;
import com.liferay.portal.kernel.dao.jdbc.CurrentConnection;
import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
import com.liferay.portal.kernel.dao.orm.DefaultActionableDynamicQuery;
import com.liferay.portal.kernel.dao.orm.FinderCacheUtil;
import com.liferay.portal.kernel.dao.orm.Property;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.dao.orm.Session;
import com.liferay.portal.kernel.dependency.manager.DependencyManagerSyncUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.language.Language;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.mass.delete.MassDeleteCacheThreadLocal;
import com.liferay.portal.kernel.model.ResourceConstants;
import com.liferay.portal.kernel.model.SystemEventConstants;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.model.WorkflowInstanceLink;
import com.liferay.portal.kernel.search.Indexable;
import com.liferay.portal.kernel.search.IndexableType;
import com.liferay.portal.kernel.security.RandomUtil;
import com.liferay.portal.kernel.security.auth.CompanyThreadLocal;
import com.liferay.portal.kernel.security.permission.ResourceActions;
import com.liferay.portal.kernel.service.ClassNameLocalService;
import com.liferay.portal.kernel.service.CompanyLocalService;
import com.liferay.portal.kernel.service.GroupLocalService;
import com.liferay.portal.kernel.service.ListTypeLocalService;
import com.liferay.portal.kernel.service.OrganizationLocalService;
import com.liferay.portal.kernel.service.PortletLocalService;
import com.liferay.portal.kernel.service.ResourceLocalService;
import com.liferay.portal.kernel.service.ResourcePermissionLocalService;
import com.liferay.portal.kernel.service.UserGroupRoleLocalService;
import com.liferay.portal.kernel.service.UserLocalService;
import com.liferay.portal.kernel.service.WorkflowInstanceLinkLocalService;
import com.liferay.portal.kernel.service.persistence.ResourcePermissionPersistence;
import com.liferay.portal.kernel.systemevent.SystemEvent;
import com.liferay.portal.kernel.transaction.TransactionCommitCallbackUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.MethodHandler;
import com.liferay.portal.kernel.util.MethodKey;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.PortalRunMode;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.TextFormatter;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import com.liferay.portal.kernel.workflow.WorkflowInstanceManager;
import com.liferay.portal.language.override.service.PLOEntryLocalService;
import com.liferay.portal.search.batch.DynamicQueryBatchIndexingActionableFactory;
import com.liferay.portal.search.localization.SearchLocalizationHelper;
import com.liferay.portal.search.spi.model.query.contributor.ModelPreFilterContributor;
import com.liferay.portal.util.PortalInstances;
import com.liferay.portal.vulcan.util.LocalizedMapUtil;
import java.sql.PreparedStatement;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
/**
* @author Marco Leo
* @author Brian Wing Shun Chan
*/
@Component(
property = "model.class.name=com.liferay.object.model.ObjectDefinition",
service = AopService.class
)
public class ObjectDefinitionLocalServiceImpl
extends ObjectDefinitionLocalServiceBaseImpl {
@Indexable(type = IndexableType.REINDEX)
@Override
public ObjectDefinition addCustomObjectDefinition(
long userId, long objectFolderId, String className,
boolean enableComments, boolean enableIndexSearch,
boolean enableLocalization, boolean enableObjectEntryDraft,
Map labelMap, String name, String panelAppOrder,
String panelCategoryKey, Map pluralLabelMap,
boolean portlet, String scope, String storageType,
List objectFields)
throws PortalException {
return _addObjectDefinition(
null, userId, objectFolderId, className, null, enableComments,
enableIndexSearch, enableLocalization, enableObjectEntryDraft,
labelMap, true, name, panelAppOrder, panelCategoryKey, null, null,
pluralLabelMap, portlet, scope, storageType, false, null, 0,
WorkflowConstants.STATUS_DRAFT, objectFields);
}
@Indexable(type = IndexableType.REINDEX)
@Override
public ObjectDefinition addObjectDefinition(
String externalReferenceCode, long userId, long objectFolderId,
boolean modifiable, boolean system)
throws PortalException {
_validateExternalReferenceCode(externalReferenceCode, system);
ObjectDefinition objectDefinition = objectDefinitionPersistence.create(
counterLocalService.increment());
objectDefinition.setExternalReferenceCode(externalReferenceCode);
User user = _userLocalService.getUser(userId);
objectDefinition.setCompanyId(user.getCompanyId());
objectDefinition.setUserId(user.getUserId());
objectDefinition.setUserName(user.getFullName());
objectDefinition.setObjectFolderId(
_getObjectFolderId(user.getCompanyId(), objectFolderId));
objectDefinition.setActive(false);
objectDefinition.setLabel(externalReferenceCode);
objectDefinition.setModifiable(modifiable);
objectDefinition.setName(externalReferenceCode);
objectDefinition.setPluralLabel(externalReferenceCode);
objectDefinition.setScope(ObjectDefinitionConstants.SCOPE_COMPANY);
objectDefinition.setStorageType(
ObjectDefinitionConstants.STORAGE_TYPE_DEFAULT);
objectDefinition.setSystem(system);
objectDefinition.setStatus(WorkflowConstants.STATUS_DRAFT);
if (objectDefinition.isUnmodifiableSystemObject() || !modifiable) {
throw new ObjectDefinitionModifiableException.MustBeModifiable();
}
objectDefinition = objectDefinitionPersistence.update(objectDefinition);
_addOrUpdateObjectDefinitionPLOEntries(objectDefinition);
_resourceLocalService.addResources(
objectDefinition.getCompanyId(), 0, objectDefinition.getUserId(),
ObjectDefinition.class.getName(),
objectDefinition.getObjectDefinitionId(), false, true, true);
_objectFolderItemLocalService.addObjectFolderItem(
userId, objectDefinition.getObjectDefinitionId(),
objectDefinition.getObjectFolderId(), 0, 0);
_addSystemObjectFields(
ObjectEntryTable.INSTANCE.getTableName(), objectDefinition,
ObjectEntryTable.INSTANCE.objectEntryId.getName(), userId);
return _updateTitleObjectFieldId(objectDefinition, null);
}
@Indexable(type = IndexableType.REINDEX)
@Override
public ObjectDefinition addOrUpdateSystemObjectDefinition(
long companyId, long objectFolderId,
SystemObjectDefinitionManager systemObjectDefinitionManager)
throws PortalException {
ObjectDefinition objectDefinition =
objectDefinitionPersistence.fetchByC_N(
companyId, systemObjectDefinitionManager.getName());
long userId = _userLocalService.getGuestUserId(companyId);
if (objectDefinition == null) {
Table table = systemObjectDefinitionManager.getTable();
Column, Long> primaryKeyColumn =
systemObjectDefinitionManager.getPrimaryKeyColumn();
objectDefinition = addSystemObjectDefinition(
systemObjectDefinitionManager.getExternalReferenceCode(),
userId, objectFolderId,
systemObjectDefinitionManager.getModelClassName(),
table.getTableName(), false, true, false,
systemObjectDefinitionManager.getLabelMap(), false,
systemObjectDefinitionManager.getName(), null, null,
primaryKeyColumn.getName(), primaryKeyColumn.getName(),
systemObjectDefinitionManager.getPluralLabelMap(), false,
systemObjectDefinitionManager.getScope(),
systemObjectDefinitionManager.getTitleObjectFieldName(),
systemObjectDefinitionManager.getVersion(),
WorkflowConstants.STATUS_APPROVED,
systemObjectDefinitionManager.getObjectFields());
_addOrUpdateObjectActions(
userId, objectDefinition.getObjectDefinitionId(),
systemObjectDefinitionManager.getObjectActions());
return objectDefinition;
}
objectDefinition.setObjectFolderId(objectFolderId);
objectDefinition.setLabelMap(
systemObjectDefinitionManager.getLabelMap());
objectDefinition.setPluralLabelMap(
systemObjectDefinitionManager.getPluralLabelMap());
objectDefinition.setVersion(systemObjectDefinitionManager.getVersion());
objectDefinition = objectDefinitionPersistence.update(objectDefinition);
List newObjectFields =
systemObjectDefinitionManager.getObjectFields();
List oldObjectFields =
_objectFieldPersistence.findByODI_DTN(
objectDefinition.getObjectDefinitionId(),
objectDefinition.getDBTableName());
for (ObjectField oldObjectField : oldObjectFields) {
if (oldObjectField.isSystem() &&
!ObjectFieldUtil.isMetadata(oldObjectField.getName()) &&
!_hasObjectField(newObjectFields, oldObjectField)) {
_objectFieldPersistence.remove(oldObjectField);
}
}
for (ObjectField newObjectField : newObjectFields) {
ObjectField oldObjectField = _objectFieldPersistence.fetchByODI_N(
objectDefinition.getObjectDefinitionId(),
newObjectField.getName());
if (oldObjectField == null) {
_objectFieldLocalService.addSystemObjectField(
newObjectField.getExternalReferenceCode(), userId,
newObjectField.getListTypeDefinitionId(),
objectDefinition.getObjectDefinitionId(),
newObjectField.getBusinessType(),
newObjectField.getDBColumnName(),
objectDefinition.getDBTableName(),
newObjectField.getDBType(), false, false, "",
newObjectField.getLabelMap(), newObjectField.isLocalized(),
newObjectField.getName(), newObjectField.getReadOnly(),
newObjectField.getReadOnlyConditionExpression(),
newObjectField.isRequired(), newObjectField.isState(),
newObjectField.getObjectFieldSettings());
}
else {
if (!Objects.equals(
oldObjectField.getDBType(),
newObjectField.getDBType()) ||
!Objects.equals(
oldObjectField.isRequired(),
newObjectField.isRequired())) {
oldObjectField.setBusinessType(
newObjectField.getBusinessType());
oldObjectField.setDBType(newObjectField.getDBType());
oldObjectField.setRequired(newObjectField.isRequired());
_objectFieldPersistence.update(oldObjectField);
}
}
}
_addOrUpdateObjectActions(
userId, objectDefinition.getObjectDefinitionId(),
systemObjectDefinitionManager.getObjectActions());
return objectDefinition;
}
@Indexable(type = IndexableType.REINDEX)
@Override
public ObjectDefinition addSystemObjectDefinition(
String externalReferenceCode, long userId, long objectFolderId,
String className, String dbTableName, boolean enableComments,
boolean enableIndexSearch, boolean enableLocalization,
Map labelMap, boolean modifiable, String name,
String panelAppOrder, String panelCategoryKey,
String pkObjectFieldDBColumnName, String pkObjectFieldName,
Map pluralLabelMap, boolean portlet, String scope,
String titleObjectFieldName, int version, int status,
List objectFields)
throws PortalException {
return _addObjectDefinition(
externalReferenceCode, userId, objectFolderId, className,
dbTableName, enableComments, enableIndexSearch, enableLocalization,
false, labelMap, modifiable, name, panelAppOrder, panelCategoryKey,
pkObjectFieldDBColumnName, pkObjectFieldName, pluralLabelMap,
portlet, scope, ObjectDefinitionConstants.STORAGE_TYPE_DEFAULT,
true, titleObjectFieldName, version, status, objectFields);
}
@Override
public void deleteCompanyObjectDefinitions(long companyId)
throws PortalException {
List objectDefinitions =
objectDefinitionPersistence.findByCompanyId(companyId);
for (ObjectDefinition objectDefinition : objectDefinitions) {
objectDefinitionLocalService.deleteObjectDefinition(
objectDefinition);
}
}
@Indexable(type = IndexableType.DELETE)
@Override
public ObjectDefinition deleteObjectDefinition(long objectDefinitionId)
throws PortalException {
ObjectDefinition objectDefinition =
objectDefinitionPersistence.findByPrimaryKey(objectDefinitionId);
return deleteObjectDefinition(objectDefinition);
}
@Indexable(type = IndexableType.DELETE)
@Override
@SystemEvent(type = SystemEventConstants.TYPE_DELETE)
public ObjectDefinition deleteObjectDefinition(
ObjectDefinition objectDefinition)
throws PortalException {
if (!PortalInstances.isCurrentCompanyInDeletionProcess() &&
!PortalRunMode.isTestMode() &&
objectDefinition.isUnmodifiableSystemObject()) {
throw new RequiredObjectDefinitionException();
}
if (objectDefinition.getRootObjectDefinitionId() != 0) {
throw new ObjectDefinitionRootObjectDefinitionIdException(
"To delete this object, you must first disable inheritance " +
"and delete its relationships",
"to-delete-this-object-you-must-first-disable-inheritance-" +
"and-delete-its-relationships");
}
if (objectDefinition.isSystem() &&
!ObjectDefinitionUtil.isInvokerBundleAllowed()) {
throw new ObjectDefinitionSystemException(
"Only allowed bundles can delete system object definitions");
}
_objectActionLocalService.deleteObjectActions(
objectDefinition.getObjectDefinitionId());
if (!objectDefinition.isUnmodifiableSystemObject()) {
_deleteObjectDefinitionPLOEntries(objectDefinition);
ActionableDynamicQuery actionableDynamicQuery =
new DefaultActionableDynamicQuery() {
@Override
protected void intervalCompleted(
long startPrimaryKey, long endPrimaryKey)
throws PortalException {
Session portletSession =
_objectEntryPersistence.openSession();
portletSession.flush();
portletSession.clear();
Session portalSession =
_resourcePermissionPersistence.openSession();
portalSession.flush();
portalSession.clear();
}
};
actionableDynamicQuery.setAddCriteriaMethod(
dynamicQuery -> {
Property nameProperty = PropertyFactoryUtil.forName(
"objectDefinitionId");
dynamicQuery.add(
nameProperty.eq(
objectDefinition.getObjectDefinitionId()));
});
actionableDynamicQuery.setBaseLocalService(
_objectEntryLocalService);
actionableDynamicQuery.setClassLoader(getClassLoader());
actionableDynamicQuery.setModelClass(ObjectEntry.class);
AtomicBoolean deletedMarker = new AtomicBoolean();
actionableDynamicQuery.setPerformActionMethod(
(ObjectEntry objectEntry) -> {
deletedMarker.set(true);
_objectEntryLocalService.deleteObjectEntry(objectEntry);
});
actionableDynamicQuery.setPrimaryKeyPropertyName("objectEntryId");
try (SafeCloseable safeCloseable =
ObjectDefinitionThreadLocal.
setDeleteObjectDefinitionIdWithSafeCloseable(
objectDefinition.getObjectDefinitionId())) {
actionableDynamicQuery.performActions();
if (deletedMarker.get()) {
_resourcePermissionLocalService.deleteResourcePermissions(
objectDefinition.getCompanyId(),
objectDefinition.getClassName(),
ResourceConstants.SCOPE_INDIVIDUAL);
_assetEntryLocalService.deleteEntries(
objectDefinition.getCompanyId(),
objectDefinition.getClassName());
_deleteFromTable(objectDefinition.getDBTableName());
_deleteFromTable(
objectDefinition.getExtensionDBTableName());
if (objectDefinition.isEnableLocalization()) {
_deleteFromTable(
objectDefinition.getLocalizationDBTableName());
}
}
}
}
for (ObjectRelationship objectRelationship :
_objectRelationshipPersistence.findByODI1_R(
objectDefinition.getObjectDefinitionId(), false)) {
_objectRelationshipLocalService.deleteObjectRelationship(
objectRelationship);
}
for (ObjectRelationship objectRelationship :
_objectRelationshipPersistence.findByODI2_R(
objectDefinition.getObjectDefinitionId(), false)) {
_objectRelationshipLocalService.deleteObjectRelationship(
objectRelationship);
}
_objectFieldLocalService.deleteObjectFieldByObjectDefinitionId(
objectDefinition.getObjectDefinitionId());
_objectFolderItemLocalService.
deleteObjectFolderItemByObjectDefinitionId(
objectDefinition.getObjectDefinitionId());
_objectLayoutLocalService.deleteObjectLayouts(
objectDefinition.getObjectDefinitionId());
_objectValidationRuleLocalService.deleteObjectValidationRules(
objectDefinition.getObjectDefinitionId());
_objectViewLocalService.deleteObjectViews(
objectDefinition.getObjectDefinitionId());
_resourceLocalService.deleteResource(
objectDefinition.getCompanyId(), ObjectDefinition.class.getName(),
ResourceConstants.SCOPE_INDIVIDUAL,
objectDefinition.getObjectDefinitionId());
if (objectDefinition.isUnmodifiableSystemObject()) {
_dropTable(objectDefinition.getExtensionDBTableName());
}
else if (objectDefinition.isApproved()) {
try (SafeCloseable safeCloseable = CompanyThreadLocal.lock(
objectDefinition.getCompanyId())) {
ObjectDefinitionResourcePermissionUtil.removeResourceActions(
_objectActionLocalService, objectDefinition,
objectDefinitionPersistence,
new ObjectDefinitionTreeFactory(
objectDefinitionLocalService,
_objectRelationshipLocalService),
_resourceActions);
}
catch (Exception exception) {
throw new PortalException(exception);
}
_dropTable(objectDefinition.getDBTableName());
_dropTable(objectDefinition.getExtensionDBTableName());
if (objectDefinition.isEnableLocalization()) {
_dropTable(objectDefinition.getLocalizationDBTableName());
}
undeployObjectDefinition(objectDefinition);
_registerTransactionCallbackForCluster(
_undeployObjectDefinitionMethodKey, objectDefinition);
}
objectDefinitionPersistence.remove(objectDefinition);
Set names = MassDeleteCacheThreadLocal.getMassDeleteCache(
ResourcePermissionLocalService.class.getName(), HashSet::new);
if (names != null) {
for (String name : names) {
_resourcePermissionLocalService.deleteResourcePermissions(name);
}
}
return objectDefinition;
}
@Override
public void deployInactiveObjectDefinition(
ObjectDefinition objectDefinition) {
undeployObjectDefinition(objectDefinition);
for (Map.Entry
>>> entry :
_inactiveObjectDefinitionsServiceRegistrationsMaps.
entrySet()) {
InactiveObjectDefinitionDeployer inactiveObjectDefinitionDeployer =
entry.getKey();
Map>> serviceRegistrationsMap =
entry.getValue();
try (SafeCloseable safeCloseable =
CompanyThreadLocal.setCompanyIdWithSafeCloseable(
objectDefinition.getCompanyId())) {
serviceRegistrationsMap.computeIfAbsent(
objectDefinition.getObjectDefinitionId(),
objectDefinitionId ->
inactiveObjectDefinitionDeployer.deploy(
objectDefinition));
}
}
}
@Override
public void deployObjectDefinition(ObjectDefinition objectDefinition) {
undeployObjectDefinition(objectDefinition);
for (Map.Entry
>>> entry :
_serviceRegistrationsMaps.entrySet()) {
ObjectDefinitionDeployer objectDefinitionDeployer = entry.getKey();
Map>> serviceRegistrationsMap =
entry.getValue();
try (SafeCloseable safeCloseable = CompanyThreadLocal.lock(
objectDefinition.getCompanyId())) {
serviceRegistrationsMap.computeIfAbsent(
objectDefinition.getObjectDefinitionId(),
objectDefinitionId -> objectDefinitionDeployer.deploy(
objectDefinition));
}
}
}
@Override
public ObjectDefinition enableAccountEntryRestricted(
ObjectRelationship objectRelationship)
throws PortalException {
ObjectDefinition objectDefinition1 = getObjectDefinition(
objectRelationship.getObjectDefinitionId1());
if (!Objects.equals(objectDefinition1.getShortName(), "AccountEntry")) {
throw new ObjectDefinitionAccountEntryRestrictedException(
"Custom object definitions can only be restricted by account " +
"entry");
}
ObjectDefinition objectDefinition2 = getObjectDefinition(
objectRelationship.getObjectDefinitionId2());
if (objectDefinition2.isAccountEntryRestricted()) {
return objectDefinition2;
}
objectDefinition2.setAccountEntryRestrictedObjectFieldId(
objectRelationship.getObjectFieldId2());
objectDefinition2.setAccountEntryRestricted(true);
return objectDefinitionPersistence.update(objectDefinition2);
}
@Override
public ObjectDefinition
enableAccountEntryRestrictedForNondefaultStorageType(
ObjectField objectField)
throws PortalException {
if (!objectField.compareBusinessType(
ObjectFieldConstants.BUSINESS_TYPE_INTEGER) &&
!objectField.compareBusinessType(
ObjectFieldConstants.BUSINESS_TYPE_LONG_INTEGER) &&
!objectField.compareBusinessType(
ObjectFieldConstants.BUSINESS_TYPE_TEXT)) {
throw new ObjectDefinitionAccountEntryRestrictedException(
"Custom object definitions can only be restricted by an " +
"integer, long integer, or text field");
}
ObjectDefinition objectDefinition = getObjectDefinition(
objectField.getObjectDefinitionId());
if (objectDefinition.isDefaultStorageType()) {
throw new UnsupportedOperationException();
}
objectDefinition.setAccountEntryRestrictedObjectFieldId(
objectField.getObjectFieldId());
objectDefinition.setAccountEntryRestricted(true);
return objectDefinitionPersistence.update(objectDefinition);
}
@Override
public ObjectDefinition fetchObjectDefinition(long companyId, String name) {
return objectDefinitionPersistence.fetchByC_N(companyId, name);
}
@Override
public ObjectDefinition fetchObjectDefinitionByClassName(
long companyId, String className) {
return objectDefinitionPersistence.fetchByC_C(companyId, className);
}
@Override
public ObjectDefinition fetchSystemObjectDefinition(String name) {
for (ObjectDefinition systemObjectDefinition :
getSystemObjectDefinitions()) {
if (Objects.equals(systemObjectDefinition.getName(), name)) {
return systemObjectDefinition;
}
}
return null;
}
@Override
public List getBoundObjectDefinitions(
long companyId, long rootObjectDefinitionId) {
return objectDefinitionPersistence.findByC_RODI(
companyId, rootObjectDefinitionId);
}
@Override
public List getCustomObjectDefinitions(int status) {
return objectDefinitionPersistence.findByS_S(false, status);
}
@Override
public ObjectDefinition getObjectDefinition(long objectDefinitionId)
throws PortalException {
return objectDefinitionPersistence.findByPrimaryKey(objectDefinitionId);
}
@Override
public ObjectDefinition getObjectDefinition(long companyId, String name)
throws PortalException {
return objectDefinitionPersistence.findByC_N(companyId, name);
}
@Override
public List getObjectDefinitions(
boolean accountEntryRestricted) {
return objectDefinitionPersistence.findByAccountEntryRestricted(
accountEntryRestricted);
}
@Override
public List getObjectDefinitions(
long companyId, boolean active, boolean system, int status) {
return objectDefinitionPersistence.findByC_A_S_S(
companyId, active, system, status);
}
@Override
public List getObjectDefinitions(
long companyId, boolean active, int status) {
return objectDefinitionPersistence.findByC_A_S(
companyId, active, status);
}
@Override
public List getObjectDefinitions(
long companyId, int status) {
return objectDefinitionPersistence.findByC_S(companyId, status);
}
@Override
public int getObjectDefinitionsCount(long companyId)
throws PortalException {
return objectDefinitionPersistence.countByCompanyId(companyId);
}
@Override
public List getObjectFolderObjectDefinitions(
long objectFolderId) {
return objectDefinitionPersistence.findByObjectFolderId(objectFolderId);
}
@Override
public int getObjectFolderObjectDefinitionsCount(long objectFolderId)
throws PortalException {
return objectDefinitionPersistence.countByObjectFolderId(
objectFolderId);
}
@Override
public List getSystemObjectDefinitions() {
return objectDefinitionPersistence.findBySystem(true);
}
@Override
public List getUnmodifiableSystemObjectDefinitions(
long companyId) {
return objectDefinitionPersistence.findByC_M_S(companyId, false, true);
}
@Override
public boolean hasObjectRelationship(long objectDefinitionId) {
int countByObjectDefinitionId1 =
_objectRelationshipPersistence.countByObjectDefinitionId1(
objectDefinitionId);
int countByObjectDefinitionId2 =
_objectRelationshipPersistence.countByObjectDefinitionId2(
objectDefinitionId);
if ((countByObjectDefinitionId1 > 0) ||
(countByObjectDefinitionId2 > 0)) {
return true;
}
return false;
}
@Indexable(type = IndexableType.REINDEX)
@Override
public ObjectDefinition publishCustomObjectDefinition(
long userId, long objectDefinitionId)
throws PortalException {
ObjectDefinition objectDefinition =
objectDefinitionPersistence.findByPrimaryKey(objectDefinitionId);
if (objectDefinition.isUnmodifiableSystemObject()) {
throw new ObjectDefinitionStatusException(
"Unmodifiable system object definition cannot be published");
}
return _publishObjectDefinition(userId, objectDefinition);
}
@Indexable(type = IndexableType.REINDEX)
@Override
public ObjectDefinition publishSystemObjectDefinition(
long userId, long objectDefinitionId)
throws PortalException {
ObjectDefinition objectDefinition =
objectDefinitionPersistence.findByPrimaryKey(objectDefinitionId);
return _publishObjectDefinition(userId, objectDefinition);
}
@Override
public void setAopProxy(Object aopProxy) {
super.setAopProxy(aopProxy);
Map>> activeServiceRegistrationsMap =
new ConcurrentHashMap<>();
InactiveObjectDefinitionDeployer inactiveObjectDefinitionDeployer =
new InactiveObjectDefinitionDeployerImpl(
_bundleContext, _objectEntryService, _objectFieldLocalService,
_objectRelatedModelsProviderRegistrarHelper,
_objectRelationshipLocalService);
Map>>
inactiveServiceRegistrationsMap = new ConcurrentHashMap<>();
ObjectDefinitionDeployer objectDefinitionDeployer =
new ObjectDefinitionDeployerImpl(
_accountEntryLocalService,
_accountEntryOrganizationRelLocalService,
_assetEntryLocalService, _bundleContext,
_dynamicQueryBatchIndexingActionableFactory, _groupLocalService,
_listTypeLocalService, _objectActionLocalService,
objectDefinitionLocalService, _objectEntryLocalService,
_objectEntryService, _objectFieldLocalService,
_objectLayoutLocalService, _objectLayoutTabLocalService,
_objectRelatedModelsProviderRegistrarHelper,
_objectRelationshipLocalService, _objectScopeProviderRegistry,
_objectViewLocalService, _organizationLocalService,
_ploEntryLocalService, _portal, _portletLocalService,
_resourceActions, _userLocalService,
_resourcePermissionLocalService, _searchLocalizationHelper,
_workflowStatusModelPreFilterContributor,
_userGroupRoleLocalService);
_companyLocalService.forEachCompanyId(
companyId -> {
for (ObjectDefinition objectDefinition :
objectDefinitionLocalService.getObjectDefinitions(
companyId, WorkflowConstants.STATUS_APPROVED)) {
if (objectDefinition.isActive()) {
activeServiceRegistrationsMap.put(
objectDefinition.getObjectDefinitionId(),
objectDefinitionDeployer.deploy(objectDefinition));
}
else {
inactiveServiceRegistrationsMap.put(
objectDefinition.getObjectDefinitionId(),
inactiveObjectDefinitionDeployer.deploy(
objectDefinition));
}
}
});
_inactiveObjectDefinitionsServiceRegistrationsMaps.put(
inactiveObjectDefinitionDeployer, inactiveServiceRegistrationsMap);
_serviceRegistrationsMaps.put(
objectDefinitionDeployer, activeServiceRegistrationsMap);
_objectDefinitionDeployerServiceTracker = new ServiceTracker<>(
_bundleContext, ObjectDefinitionDeployer.class,
new ServiceTrackerCustomizer
() {
@Override
public ObjectDefinitionDeployer addingService(
ServiceReference
serviceReference) {
return _addingObjectDefinitionDeployer(
_bundleContext.getService(serviceReference));
}
@Override
public void modifiedService(
ServiceReference serviceReference,
ObjectDefinitionDeployer objectDefinitionDeployer) {
}
@Override
public void removedService(
ServiceReference serviceReference,
ObjectDefinitionDeployer objectDefinitionDeployer) {
_companyLocalService.forEachCompanyId(
companyId -> {
for (ObjectDefinition objectDefinition :
objectDefinitionLocalService.
getObjectDefinitions(
companyId,
WorkflowConstants.
STATUS_APPROVED)) {
if (objectDefinition.isActive()) {
objectDefinitionDeployer.undeploy(
objectDefinition);
}
}
});
Map>>
serviceRegistrationsMap =
_serviceRegistrationsMaps.remove(
objectDefinitionDeployer);
for (List> serviceRegistrations :
serviceRegistrationsMap.values()) {
for (ServiceRegistration> serviceRegistration :
serviceRegistrations) {
serviceRegistration.unregister();
}
}
_bundleContext.ungetService(serviceReference);
}
});
DependencyManagerSyncUtil.registerSyncCallable(
() -> {
_objectDefinitionDeployerServiceTracker.open();
return null;
});
}
@Override
public void undeployObjectDefinition(ObjectDefinition objectDefinition) {
if (objectDefinition.isUnmodifiableSystemObject()) {
return;
}
for (Map.Entry
>>> entry :
_serviceRegistrationsMaps.entrySet()) {
ObjectDefinitionDeployer objectDefinitionDeployer = entry.getKey();
objectDefinitionDeployer.undeploy(objectDefinition);
Map>> serviceRegistrationsMap =
entry.getValue();
List> serviceRegistrations =
serviceRegistrationsMap.remove(
objectDefinition.getObjectDefinitionId());
if (serviceRegistrations != null) {
for (ServiceRegistration> serviceRegistration :
serviceRegistrations) {
serviceRegistration.unregister();
}
}
}
_invalidatePortalCache(objectDefinition);
}
@Indexable(type = IndexableType.REINDEX)
@Override
public ObjectDefinition updateCustomObjectDefinition(
String externalReferenceCode, long objectDefinitionId,
long accountEntryRestrictedObjectFieldId,
long descriptionObjectFieldId, long objectFolderId,
long titleObjectFieldId, boolean accountEntryRestricted,
boolean active, String className, boolean enableCategorization,
boolean enableComments, boolean enableIndexSearch,
boolean enableLocalization, boolean enableObjectEntryDraft,
boolean enableObjectEntryHistory, Map labelMap,
String name, String panelAppOrder, String panelCategoryKey,
boolean portlet, Map pluralLabelMap, String scope,
int status)
throws PortalException {
ObjectDefinition objectDefinition =
objectDefinitionPersistence.findByPrimaryKey(objectDefinitionId);
if (objectDefinition.isUnmodifiableSystemObject()) {
throw new ObjectDefinitionStatusException(
"Object definition " + objectDefinition);
}
if (objectDefinition.isRootDescendantNode()) {
String errorMessage =
"cannot be changed when the object definition is a root " +
"descendant node";
if (!Objects.equals(
objectDefinition.getAccountEntryRestrictedObjectFieldId(),
accountEntryRestrictedObjectFieldId)) {
throw new ObjectDefinitionAccountEntryRestrictedObjectFieldIdException(
"Account entry restriction object field ID " +
errorMessage);
}
else if (!Objects.equals(
objectDefinition.isAccountEntryRestricted(),
accountEntryRestricted)) {
throw new ObjectDefinitionAccountEntryRestrictedException(
"Account entry restriction " + errorMessage);
}
else if (!Objects.equals(
objectDefinition.getPanelCategoryKey(),
GetterUtil.getString(panelCategoryKey))) {
throw new ObjectDefinitionPanelCategoryKeyException(
"Panel category key " + errorMessage);
}
else if (!Objects.equals(objectDefinition.isPortlet(), portlet)) {
throw new ObjectDefinitionPortletException(
"Portlet " + errorMessage);
}
else if (!Objects.equals(objectDefinition.getScope(), scope)) {
throw new ObjectDefinitionScopeException(
"Scope " + errorMessage);
}
}
return _updateObjectDefinition(
externalReferenceCode, objectDefinition,
accountEntryRestrictedObjectFieldId, descriptionObjectFieldId,
objectFolderId, titleObjectFieldId, accountEntryRestricted, active,
className, null, enableCategorization, enableComments,
enableIndexSearch, enableLocalization, enableObjectEntryDraft,
enableObjectEntryHistory, labelMap, name, panelAppOrder,
panelCategoryKey, portlet, null, null, pluralLabelMap, scope,
status);
}
@Indexable(type = IndexableType.REINDEX)
@Override
public ObjectDefinition updateExternalReferenceCode(
long objectDefinitionId, String externalReferenceCode)
throws PortalException {
ObjectDefinition objectDefinition =
objectDefinitionPersistence.findByPrimaryKey(objectDefinitionId);
_validateExternalReferenceCode(
externalReferenceCode, objectDefinition.isSystem());
objectDefinition.setExternalReferenceCode(externalReferenceCode);
return objectDefinitionPersistence.update(objectDefinition);
}
@Indexable(type = IndexableType.REINDEX)
@Override
public ObjectDefinition updateObjectFolderId(
long objectDefinitionId, long objectFolderId)
throws PortalException {
ObjectDefinition objectDefinition =
objectDefinitionPersistence.findByPrimaryKey(objectDefinitionId);
long oldObjectFolderId = objectDefinition.getObjectFolderId();
objectDefinition.setObjectFolderId(
_getObjectFolderId(
objectDefinition.getCompanyId(), objectFolderId));
objectDefinition = objectDefinitionPersistence.update(objectDefinition);
_objectFolderItemLocalService.updateObjectFolderObjectFolderItem(
objectDefinitionId, objectDefinition.getObjectFolderId(),
oldObjectFolderId);
return objectDefinition;
}
@Indexable(type = IndexableType.REINDEX)
@Override
public ObjectDefinition updatePortlet(long objectDefinitionId)
throws PortalException {
ObjectDefinition objectDefinition =
objectDefinitionPersistence.findByPrimaryKey(objectDefinitionId);
if (objectDefinition.isPortlet() &&
objectDefinition.isRootDescendantNode()) {
objectDefinition.setPortlet(false);
return objectDefinitionPersistence.update(objectDefinition);
}
return objectDefinition;
}
@Indexable(type = IndexableType.REINDEX)
@Override
public ObjectDefinition updateRootObjectDefinitionId(
long objectDefinitionId, long rootObjectDefinitionId)
throws PortalException {
ObjectDefinition objectDefinition =
objectDefinitionPersistence.findByPrimaryKey(objectDefinitionId);
if (rootObjectDefinitionId == 0) {
objectDefinition.setRootObjectDefinitionId(0);
return objectDefinitionPersistence.update(objectDefinition);
}
ObjectDefinition rootObjectDefinition =
objectDefinitionPersistence.findByPrimaryKey(
rootObjectDefinitionId);
if (!rootObjectDefinition.isRootNode() &&
(objectDefinitionId != rootObjectDefinitionId)) {
throw new ObjectDefinitionRootObjectDefinitionIdException(
"Object definition " + rootObjectDefinitionId +
" is not a root object definition");
}
objectDefinition.setRootObjectDefinitionId(rootObjectDefinitionId);
return objectDefinitionPersistence.update(objectDefinition);
}
@Indexable(type = IndexableType.REINDEX)
@Override
public ObjectDefinition updateSystemObjectDefinition(
String externalReferenceCode, long objectDefinitionId,
long objectFolderId, long titleObjectFieldId)
throws PortalException {
ObjectDefinition objectDefinition =
objectDefinitionPersistence.fetchByPrimaryKey(objectDefinitionId);
_validateExternalReferenceCode(
externalReferenceCode, objectDefinition.isSystem());
_validateObjectFieldId(objectDefinition, titleObjectFieldId);
long oldObjectFolderId = objectDefinition.getObjectFolderId();
objectDefinition.setExternalReferenceCode(externalReferenceCode);
objectDefinition.setObjectFolderId(
_getObjectFolderId(
objectDefinition.getCompanyId(), objectFolderId));
objectDefinition.setTitleObjectFieldId(titleObjectFieldId);
objectDefinition = objectDefinitionPersistence.update(objectDefinition);
_objectFolderItemLocalService.updateObjectFolderObjectFolderItem(
objectDefinitionId, objectDefinition.getObjectFolderId(),
oldObjectFolderId);
return objectDefinition;
}
@Indexable(type = IndexableType.REINDEX)
@Override
public ObjectDefinition updateTitleObjectFieldId(
long objectDefinitionId, long titleObjectFieldId)
throws PortalException {
ObjectDefinition objectDefinition =
objectDefinitionPersistence.fetchByPrimaryKey(objectDefinitionId);
_validateObjectFieldId(objectDefinition, titleObjectFieldId);
objectDefinition.setTitleObjectFieldId(titleObjectFieldId);
return objectDefinitionPersistence.update(objectDefinition);
}
@Override
public void updateUserId(long companyId, long oldUserId, long newUserId)
throws PortalException {
for (ObjectDefinition objectDefinition :
objectDefinitionPersistence.findByC_U(companyId, oldUserId)) {
objectDefinition.setUserId(newUserId);
objectDefinitionPersistence.update(objectDefinition);
}
}
@Activate
protected void activate(BundleContext bundleContext) {
_bundleContext = bundleContext;
}
@Deactivate
@Override
protected void deactivate() {
super.deactivate();
if (_objectDefinitionDeployerServiceTracker != null) {
_objectDefinitionDeployerServiceTracker.close();
}
}
@Override
protected void runSQL(String sql) {
ObjectDBManagerUtil.runSQL(
objectDefinitionPersistence.getDataSource(), _log, sql);
}
private ObjectDefinitionDeployer _addingObjectDefinitionDeployer(
ObjectDefinitionDeployer objectDefinitionDeployer) {
Map>> serviceRegistrationsMap =
new ConcurrentHashMap<>();
_companyLocalService.forEachCompanyId(
companyId -> {
for (ObjectDefinition objectDefinition :
objectDefinitionLocalService.getObjectDefinitions(
companyId, WorkflowConstants.STATUS_APPROVED)) {
if (objectDefinition.isActive()) {
serviceRegistrationsMap.put(
objectDefinition.getObjectDefinitionId(),
objectDefinitionDeployer.deploy(objectDefinition));
}
}
});
_serviceRegistrationsMaps.put(
objectDefinitionDeployer, serviceRegistrationsMap);
return objectDefinitionDeployer;
}
private ObjectDefinition _addObjectDefinition(
String externalReferenceCode, long userId, long objectFolderId,
String className, String dbTableName, boolean enableComments,
boolean enableIndexSearch, boolean enableLocalization,
boolean enableObjectEntryDraft, Map labelMap,
boolean modifiable, String name, String panelAppOrder,
String panelCategoryKey, String pkObjectFieldDBColumnName,
String pkObjectFieldName, Map pluralLabelMap,
boolean portlet, String scope, String storageType, boolean system,
String titleObjectFieldName, int version, int status,
List objectFields)
throws PortalException {
User user = _userLocalService.getUser(userId);
name = _getName(name, system);
String shortName = ObjectDefinitionImpl.getShortName(name);
dbTableName = _getDBTableName(
dbTableName, modifiable, name, system, user.getCompanyId(),
shortName);
pkObjectFieldName = _getPKObjectFieldName(
pkObjectFieldName, modifiable, system, shortName);
pkObjectFieldDBColumnName = _getPKObjectFieldDBColumnName(
pkObjectFieldDBColumnName, pkObjectFieldName, modifiable, system);
storageType = Validator.isNotNull(storageType) ? storageType :
ObjectDefinitionConstants.STORAGE_TYPE_DEFAULT;
_validateExternalReferenceCode(externalReferenceCode, system);
_validateClassName(
0, user.getCompanyId(), className, modifiable, system);
_validateEnableComments(
enableComments, modifiable, storageType, system);
_validateLabel(labelMap);
_validateName(0, user.getCompanyId(), modifiable, name, system);
_validatePluralLabel(pluralLabelMap);
_validateScope(scope, storageType);
_validateVersion(system, version);
ObjectDefinition objectDefinition = objectDefinitionPersistence.create(
counterLocalService.increment());
objectDefinition.setExternalReferenceCode(externalReferenceCode);
objectDefinition.setCompanyId(user.getCompanyId());
objectDefinition.setUserId(user.getUserId());
objectDefinition.setUserName(user.getFullName());
objectDefinition.setObjectFolderId(
_getObjectFolderId(user.getCompanyId(), objectFolderId));
objectDefinition.setActive(
_isUnmodifiableSystemObject(modifiable, system));
objectDefinition.setClassName(
_getClassName(user.getCompanyId(), className, modifiable, system));
objectDefinition.setDBTableName(dbTableName);
objectDefinition.setEnableCategorization(
!objectDefinition.isUnmodifiableSystemObject() &&
StringUtil.equals(
storageType, ObjectDefinitionConstants.STORAGE_TYPE_DEFAULT));
objectDefinition.setEnableComments(enableComments);
objectDefinition.setEnableIndexSearch(enableIndexSearch);
objectDefinition.setEnableLocalization(enableLocalization);
objectDefinition.setEnableObjectEntryDraft(enableObjectEntryDraft);
objectDefinition.setLabelMap(labelMap, LocaleUtil.getSiteDefault());
objectDefinition.setModifiable(modifiable);
objectDefinition.setName(name);
objectDefinition.setPanelAppOrder(panelAppOrder);
objectDefinition.setPanelCategoryKey(panelCategoryKey);
objectDefinition.setPKObjectFieldDBColumnName(
pkObjectFieldDBColumnName);
objectDefinition.setPKObjectFieldName(pkObjectFieldName);
objectDefinition.setPluralLabelMap(pluralLabelMap);
objectDefinition.setPortlet(portlet);
objectDefinition.setScope(scope);
objectDefinition.setStorageType(
Validator.isNotNull(storageType) ? storageType :
ObjectDefinitionConstants.STORAGE_TYPE_DEFAULT);
objectDefinition.setSystem(system);
objectDefinition.setVersion(version);
objectDefinition.setStatus(status);
objectDefinition = objectDefinitionPersistence.update(objectDefinition);
_resourceLocalService.addResources(
objectDefinition.getCompanyId(), 0, objectDefinition.getUserId(),
ObjectDefinition.class.getName(),
objectDefinition.getObjectDefinitionId(), false, true, true);
if (objectDefinition.isModifiable() ||
!objectDefinition.isUnmodifiableSystemObject()) {
_addOrUpdateObjectDefinitionPLOEntries(objectDefinition);
dbTableName = "ObjectEntry";
}
_addSystemObjectFields(
dbTableName, objectDefinition, pkObjectFieldName, userId);
if (objectFields != null) {
for (ObjectField objectField : objectFields) {
if (objectDefinition.isUnmodifiableSystemObject() ||
objectField.isSystem()) {
_objectFieldLocalService.addOrUpdateSystemObjectField(
objectField.getExternalReferenceCode(), userId,
objectField.getListTypeDefinitionId(),
objectDefinition.getObjectDefinitionId(),
objectField.getBusinessType(),
objectField.getDBColumnName(),
objectDefinition.getDBTableName(),
objectField.getDBType(), objectField.isIndexed(),
objectField.isIndexedAsKeyword(),
objectField.getIndexedLanguageId(),
objectField.getLabelMap(), objectField.isLocalized(),
objectField.getName(), objectField.getReadOnly(),
objectField.getReadOnlyConditionExpression(),
objectField.isRequired(), objectField.isState(),
objectField.getObjectFieldSettings());
}
else {
_objectFieldLocalService.addCustomObjectField(
objectField.getExternalReferenceCode(), userId,
objectField.getListTypeDefinitionId(),
objectDefinition.getObjectDefinitionId(),
objectField.getBusinessType(), objectField.getDBType(),
objectField.isIndexed(),
objectField.isIndexedAsKeyword(),
objectField.getIndexedLanguageId(),
objectField.getLabelMap(), objectField.isLocalized(),
objectField.getName(), objectField.getReadOnly(),
objectField.getReadOnlyConditionExpression(),
objectField.isRequired(), objectField.isState(),
objectField.getObjectFieldSettings());
}
}
}
_objectFolderItemLocalService.addObjectFolderItem(
userId, objectDefinition.getObjectDefinitionId(),
objectDefinition.getObjectFolderId(), 0, 0);
objectDefinition = _updateTitleObjectFieldId(
objectDefinition, titleObjectFieldName);
if (objectDefinition.isUnmodifiableSystemObject()) {
_createTable(
DynamicObjectDefinitionTableFactory.createExtension(
objectDefinition, _objectFieldLocalService));
}
return objectDefinition;
}
private void _addOrUpdateObjectActions(
long userId, long objectDefinitionId,
List objectActions)
throws PortalException {
for (ObjectAction objectAction : objectActions) {
_objectActionLocalService.addOrUpdateObjectAction(
objectAction.getExternalReferenceCode(), 0, userId,
objectDefinitionId, objectAction.isActive(),
objectAction.getConditionExpression(),
objectAction.getDescription(),
objectAction.getErrorMessageMap(), objectAction.getLabelMap(),
objectAction.getName(),
objectAction.getObjectActionExecutorKey(),
objectAction.getObjectActionTriggerKey(),
objectAction.getParametersUnicodeProperties(),
objectAction.isSystem());
}
}
private void _addOrUpdateObjectDefinitionPLOEntries(
ObjectDefinition objectDefinition)
throws PortalException {
for (Locale locale : _language.getAvailableLocales()) {
String languageId = LocaleUtil.toLanguageId(locale);
_ploEntryLocalService.addOrUpdatePLOEntry(
objectDefinition.getCompanyId(), objectDefinition.getUserId(),
"model.resource." + objectDefinition.getClassName(), languageId,
objectDefinition.getLabel(locale));
_ploEntryLocalService.addOrUpdatePLOEntry(
objectDefinition.getCompanyId(), objectDefinition.getUserId(),
"model.resource." + objectDefinition.getResourceName(),
languageId, objectDefinition.getPluralLabel(locale));
}
}
private void _addSystemObjectFields(
String dbTableName, ObjectDefinition objectDefinition,
String pkObjectFieldName, long userId)
throws PortalException {
_objectFieldLocalService.addSystemObjectField(
null, userId, 0, objectDefinition.getObjectDefinitionId(),
ObjectFieldConstants.BUSINESS_TYPE_TEXT,
ObjectEntryTable.INSTANCE.userName.getName(), dbTableName,
ObjectFieldConstants.DB_TYPE_STRING, false, false, null,
LocalizedMapUtil.getLocalizedMap(
_language.get(LocaleUtil.getDefault(), "author")),
false, "creator", ObjectFieldConstants.READ_ONLY_FALSE, null, false,
false, null);
_objectFieldLocalService.addSystemObjectField(
null, userId, 0, objectDefinition.getObjectDefinitionId(),
ObjectFieldConstants.BUSINESS_TYPE_DATE,
ObjectEntryTable.INSTANCE.createDate.getName(), dbTableName,
ObjectFieldConstants.DB_TYPE_DATE, false, false, null,
LocalizedMapUtil.getLocalizedMap(
_language.get(LocaleUtil.getDefault(), "create-date")),
false, "createDate", ObjectFieldConstants.READ_ONLY_FALSE, null,
false, false, null);
_objectFieldLocalService.addSystemObjectField(
null, userId, 0, objectDefinition.getObjectDefinitionId(),
ObjectFieldConstants.BUSINESS_TYPE_TEXT,
ObjectEntryTable.INSTANCE.externalReferenceCode.getName(),
dbTableName, ObjectFieldConstants.DB_TYPE_STRING, false, false,
null,
LocalizedMapUtil.getLocalizedMap(
_language.get(
LocaleUtil.getDefault(), "external-reference-code")),
false, "externalReferenceCode",
ObjectFieldConstants.READ_ONLY_FALSE, null, false, false, null);
String dbColumnName = ObjectEntryTable.INSTANCE.objectEntryId.getName();
if (objectDefinition.isUnmodifiableSystemObject()) {
dbColumnName = pkObjectFieldName;
}
_objectFieldLocalService.addSystemObjectField(
null, userId, 0, objectDefinition.getObjectDefinitionId(),
ObjectFieldConstants.BUSINESS_TYPE_LONG_INTEGER, dbColumnName,
dbTableName, ObjectFieldConstants.DB_TYPE_LONG, true, true, null,
LocalizedMapUtil.getLocalizedMap(
_language.get(LocaleUtil.getDefault(), "id")),
false, "id", ObjectFieldConstants.READ_ONLY_FALSE, null, false,
false, null);
_objectFieldLocalService.addSystemObjectField(
null, userId, 0, objectDefinition.getObjectDefinitionId(),
ObjectFieldConstants.BUSINESS_TYPE_DATE,
ObjectEntryTable.INSTANCE.modifiedDate.getName(), dbTableName,
ObjectFieldConstants.DB_TYPE_DATE, false, false, null,
LocalizedMapUtil.getLocalizedMap(
_language.get(LocaleUtil.getDefault(), "modified-date")),
false, "modifiedDate", ObjectFieldConstants.READ_ONLY_FALSE, null,
false, false, null);
_objectFieldLocalService.addSystemObjectField(
null, userId, 0, objectDefinition.getObjectDefinitionId(),
ObjectFieldConstants.BUSINESS_TYPE_TEXT,
ObjectEntryTable.INSTANCE.status.getName(), dbTableName,
ObjectFieldConstants.DB_TYPE_INTEGER, false, false, null,
LocalizedMapUtil.getLocalizedMap(
_language.get(LocaleUtil.getDefault(), "status")),
false, "status", ObjectFieldConstants.READ_ONLY_FALSE, null, false,
false, null);
}
private void _createLocalizationTable(
DynamicObjectDefinitionLocalizationTable
dynamicObjectDefinitionLocalizedTable) {
if (dynamicObjectDefinitionLocalizedTable == null) {
return;
}
runSQL(dynamicObjectDefinitionLocalizedTable.getCreateTableSQL());
}
private void _createTable(
DynamicObjectDefinitionTable dynamicObjectDefinitionTable)
throws PortalException {
runSQL(dynamicObjectDefinitionTable.getCreateTableSQL());
for (ObjectField objectField :
dynamicObjectDefinitionTable.getObjectFields()) {
if (!StringUtil.equals(
objectField.getBusinessType(),
ObjectFieldConstants.BUSINESS_TYPE_RELATIONSHIP)) {
continue;
}
ObjectDBManagerUtil.createIndexMetadata(
_currentConnection.getConnection(
objectDefinitionPersistence.getDataSource()),
dynamicObjectDefinitionTable.getTableName(), false,
objectField.getDBColumnName());
}
}
private void _deleteFromTable(String dbTableName) throws PortalException {
Session session = objectDefinitionPersistence.openSession();
try {
session.apply(
connection -> {
try (PreparedStatement preparedStatement =
connection.prepareStatement(
"delete from " + dbTableName)) {
preparedStatement.executeUpdate();
}
});
}
finally {
objectDefinitionPersistence.closeSession(session);
}
FinderCacheUtil.clearDSLQueryCache(dbTableName);
}
private void _deleteObjectDefinitionPLOEntries(
ObjectDefinition objectDefinition) {
_ploEntryLocalService.deletePLOEntries(
objectDefinition.getCompanyId(),
"model.resource." + objectDefinition.getResourceName());
_ploEntryLocalService.deletePLOEntries(
objectDefinition.getCompanyId(),
"model.resource." + objectDefinition.getClassName());
}
private void _dropTable(String dbTableName) {
runSQL("DROP_TABLE_IF_EXISTS(" + dbTableName + ")");
}
private String _getClassName(
long companyId, String className, boolean modifiable, boolean system) {
if (Validator.isNotNull(className) ||
_isUnmodifiableSystemObject(modifiable, system)) {
return className;
}
while (true) {
StringBuilder sb = new StringBuilder();
sb.append(
ObjectDefinitionConstants.
CLASS_NAME_PREFIX_CUSTOM_OBJECT_DEFINITION);
sb.append(StringUtil.toUpperCase(StringUtil.randomId(1)));
sb.append(RandomUtil.nextInt(10));
sb.append(StringUtil.toUpperCase(StringUtil.randomId(1)));
sb.append(RandomUtil.nextInt(10));
ObjectDefinition existingObjectDefinition =
objectDefinitionPersistence.fetchByC_C(
companyId, sb.toString());
if (existingObjectDefinition == null) {
className = sb.toString();
break;
}
}
return className;
}
private String _getDBTableName(
String dbTableName, boolean modifiable, String name, boolean system,
Long companyId, String shortName) {
if (Validator.isNotNull(dbTableName)) {
return dbTableName;
}
if (_isUnmodifiableSystemObject(modifiable, system)) {
return name;
}
// See DBInspector.java#isObjectTable
String prefix = "O_";
if (modifiable && system) {
prefix =
ObjectDefinitionConstants.
EXTERNAL_REFERENCE_CODE_PREFIX_SYSTEM_OBJECT_DEFINITION;
}
return StringBundler.concat(
prefix, companyId, StringPool.UNDERLINE, shortName);
}
private String _getName(String name, boolean system) {
name = StringUtil.trim(name);
if (!system) {
name = "C_" + name;
}
return name;
}
private long _getObjectFolderId(long companyId, long objectFolderId)
throws PortalException {
if (objectFolderId == 0) {
ObjectFolder objectFolder =
_objectFolderLocalService.getDefaultObjectFolder(companyId);
return objectFolder.getObjectFolderId();
}
_objectFolderPersistence.findByPrimaryKey(objectFolderId);
return objectFolderId;
}
private String _getPKObjectFieldDBColumnName(
String pkObjectFieldDBColumnName, String pkObjectFieldName,
boolean modifiable, boolean system) {
if (Validator.isNotNull(pkObjectFieldDBColumnName)) {
return pkObjectFieldDBColumnName;
}
if (_isUnmodifiableSystemObject(modifiable, system)) {
return pkObjectFieldName;
}
return pkObjectFieldName + StringPool.UNDERLINE;
}
private String _getPKObjectFieldName(
String pkObjectFieldName, boolean modifiable, boolean system,
String shortName) {
if (Validator.isNotNull(pkObjectFieldName)) {
return pkObjectFieldName;
}
pkObjectFieldName = TextFormatter.format(
shortName + "Id", TextFormatter.I);
if (_isUnmodifiableSystemObject(modifiable, system)) {
return pkObjectFieldName;
}
if (modifiable && system) {
String prefix =
ObjectDefinitionConstants.
EXTERNAL_REFERENCE_CODE_PREFIX_SYSTEM_OBJECT_DEFINITION;
return StringUtil.toLowerCase(prefix) + pkObjectFieldName;
}
return "c_" + pkObjectFieldName;
}
private boolean _hasObjectField(
List newObjectFields, ObjectField oldObjectField) {
for (ObjectField newObjectField : newObjectFields) {
if (Objects.equals(
newObjectField.getName(), oldObjectField.getName())) {
return true;
}
}
return false;
}
private void _invalidatePortalCache(ObjectDefinition objectDefinition) {
List layoutClassedModelUsages =
_layoutClassedModelUsageLocalService.getLayoutClassedModelUsages(
objectDefinition.getCompanyId(),
_classNameLocalService.getClassNameId(
objectDefinition.getClassName()),
_portal.getClassNameId(FragmentEntryLink.class));
for (LayoutClassedModelUsage layoutClassedModelUsage :
layoutClassedModelUsages) {
_fragmentEntryLinkCache.removeFragmentEntryLinkCache(
GetterUtil.getLong(layoutClassedModelUsage.getContainerKey()));
}
}
private boolean _isUnmodifiableSystemObject(
boolean modifiable, boolean system) {
if (!modifiable && system) {
return true;
}
return false;
}
private ObjectDefinition _publishObjectDefinition(
long userId, ObjectDefinition objectDefinition)
throws PortalException {
if (objectDefinition.isApproved()) {
throw new ObjectDefinitionStatusException(
"The object definition is already published",
"the-object-definition-is-already-published");
}
List objectFields =
_objectFieldPersistence.findByObjectDefinitionId(
objectDefinition.getObjectDefinitionId());
if (!objectDefinition.isEnableLocalization() &&
ListUtil.exists(objectFields, ObjectFieldModel::isLocalized)) {
throw new ObjectDefinitionEnableLocalizationException(
"You cannot disable entry translation for the object " +
"definition because translation is enabled for custom " +
"fields",
"you-cannot-disable-entry-translation-for-the-object-" +
"definition-because-translation-is-enabled-for-custom-" +
"fields");
}
if (!ListUtil.exists(
objectFields, objectField -> !objectField.isMetadata())) {
throw new ObjectDefinitionStatusException(
"At least one object field must be added when publishing the " +
"object definition",
"at-least-one-object-field-must-be-added");
}
if ((objectDefinition.getStatus() == WorkflowConstants.STATUS_DRAFT) &&
objectDefinition.isRootNode()) {
for (ObjectRelationship objectRelationship :
_objectRelationshipLocalService.getObjectRelationships(
objectDefinition.getObjectDefinitionId())) {
int objectEntriesCount =
_objectEntryLocalService.getObjectEntriesCount(
objectRelationship.getObjectDefinitionId2());
if (objectEntriesCount > 0) {
throw new ObjectRelationshipEdgeException(
StringBundler.concat(
"There must be no unrelated object entries when ",
"both object definitions are published so that ",
"the object relationship can be an edge to a root ",
"context"),
StringBundler.concat(
"there-must-be-no-unrelated-object-entries-when-",
"both-object-definitions-are-published-so-that-",
"the-object-relationship-can-be-an-edge-to-a-root",
"context"));
}
}
}
objectDefinition.setActive(true);
if (objectDefinition.isRootDescendantNode()) {
objectDefinition.setPanelCategoryKey(StringPool.BLANK);
}
objectDefinition.setStatus(WorkflowConstants.STATUS_APPROVED);
objectDefinition = objectDefinitionPersistence.update(objectDefinition);
objectDefinition = _updateNodeObjectDefinition(objectDefinition);
_updateDescendantNodeObjectDefinitions(objectDefinition);
_createLocalizationTable(
DynamicObjectDefinitionLocalizationTableFactory.create(
objectDefinition, _objectFieldLocalService));
_createTable(
DynamicObjectDefinitionTableFactory.create(
objectDefinition, _objectFieldLocalService));
_createTable(
DynamicObjectDefinitionTableFactory.createExtension(
objectDefinition, _objectFieldLocalService));
for (ObjectRelationship objectRelationship :
_objectRelationshipLocalService.getObjectRelationships(
objectDefinition.getObjectDefinitionId(),
ObjectRelationshipConstants.TYPE_MANY_TO_MANY)) {
_objectRelationshipLocalService.
createManyToManyObjectRelationshipTable(
userId, objectRelationship);
}
deployObjectDefinition(objectDefinition);
_registerTransactionCallbackForCluster(
_deployObjectDefinitionMethodKey, objectDefinition);
return objectDefinition;
}
private void _registerTransactionCallbackForCluster(
MethodKey methodKey, ObjectDefinition objectDefinition) {
if (ClusterExecutorUtil.isEnabled()) {
TransactionCommitCallbackUtil.registerCallback(
() -> {
ClusterRequest clusterRequest =
ClusterRequest.createMulticastRequest(
new MethodHandler(methodKey, objectDefinition),
true);
clusterRequest.setFireAndForget(true);
ClusterExecutorUtil.execute(clusterRequest);
return null;
});
}
}
private void _updateDescendantNodeObjectDefinitions(
ObjectDefinition objectDefinition1)
throws PortalException {
List objectRelationships =
_objectRelationshipPersistence.findByODI1_E(
objectDefinition1.getObjectDefinitionId(), true);
if (objectRelationships.isEmpty()) {
return;
}
deployObjectDefinition(objectDefinition1);
boolean containsDraftDescendantNodeObjectDefinitions = false;
ObjectDefinitionTreeFactory objectDefinitionTreeFactory =
new ObjectDefinitionTreeFactory(
objectDefinitionLocalService, _objectRelationshipLocalService);
for (ObjectRelationship objectRelationship : objectRelationships) {
ObjectDefinition objectDefinition2 =
objectDefinitionPersistence.findByPrimaryKey(
objectRelationship.getObjectDefinitionId2());
if (!objectDefinition2.isApproved()) {
containsDraftDescendantNodeObjectDefinitions = true;
continue;
}
Tree tree = objectDefinitionTreeFactory.create(
objectRelationship.getObjectDefinitionId2());
Iterator iterator = tree.iterator();
while (iterator.hasNext()) {
Node node = iterator.next();
ObjectDefinition nodeObjectDefinition =
objectDefinitionLocalService.getObjectDefinition(
node.getPrimaryKey());
String previousRESTContextPath =
nodeObjectDefinition.getRESTContextPath();
nodeObjectDefinition.setRootObjectDefinitionId(
objectDefinition1.getRootObjectDefinitionId());
nodeObjectDefinition.setPortlet(false);
nodeObjectDefinition = objectDefinitionPersistence.update(
nodeObjectDefinition);
nodeObjectDefinition.setPreviousRESTContextPath(
previousRESTContextPath);
deployObjectDefinition(nodeObjectDefinition);
}
}
if (containsDraftDescendantNodeObjectDefinitions) {
Tree tree = objectDefinitionTreeFactory.create(
false, objectDefinition1.getObjectDefinitionId());
Node rootNode = tree.getRootNode();
for (Node childNode : rootNode.getChildNodes()) {
Iterator iterator = tree.iterator(
childNode.getPrimaryKey());
while (iterator.hasNext()) {
Node node = iterator.next();
ObjectDefinition nodeObjectDefinition =
objectDefinitionLocalService.getObjectDefinition(
node.getPrimaryKey());
nodeObjectDefinition.setRootObjectDefinitionId(
childNode.getPrimaryKey());
objectDefinitionPersistence.update(nodeObjectDefinition);
}
}
}
}
private ObjectDefinition _updateNodeObjectDefinition(
ObjectDefinition objectDefinition2)
throws PortalException {
ObjectRelationship objectRelationship =
_objectRelationshipPersistence.fetchByODI2_E(
objectDefinition2.getObjectDefinitionId(), true);
if (objectRelationship == null) {
return objectDefinition2;
}
ObjectDefinition objectDefinition1 =
objectDefinitionLocalService.getObjectDefinition(
objectRelationship.getObjectDefinitionId1());
String previousRESTContextPath = objectDefinition2.getRESTContextPath();
if (objectDefinition1.isApproved()) {
objectDefinition2.setRootObjectDefinitionId(
objectDefinition1.getRootObjectDefinitionId());
}
else {
objectDefinition2.setRootObjectDefinitionId(
objectDefinition2.getObjectDefinitionId());
}
objectDefinition2 = objectDefinitionPersistence.update(
objectDefinition2);
objectDefinition2.setPreviousRESTContextPath(previousRESTContextPath);
return objectDefinition2;
}
private ObjectDefinition _updateObjectDefinition(
String externalReferenceCode, ObjectDefinition objectDefinition,
long accountEntryRestrictedObjectFieldId,
long descriptionObjectFieldId, long objectFolderId,
long titleObjectFieldId, boolean accountEntryRestricted,
boolean active, String className, String dbTableName,
boolean enableCategorization, boolean enableComments,
boolean enableIndexSearch, boolean enableLocalization,
boolean enableObjectEntryDraft, boolean enableObjectEntryHistory,
Map labelMap, String name, String panelAppOrder,
String panelCategoryKey, boolean portlet,
String pkObjectFieldDBColumnName, String pkObjectFieldName,
Map pluralLabelMap, String scope, int status)
throws PortalException {
long oldObjectFolderId = objectDefinition.getObjectFolderId();
boolean oldActive = objectDefinition.isActive();
String oldClassName = objectDefinition.getClassName();
_validateExternalReferenceCode(
externalReferenceCode, objectDefinition.isSystem());
_validateAccountEntryRestrictedObjectFieldId(
accountEntryRestrictedObjectFieldId, accountEntryRestricted,
objectDefinition);
_validateObjectFieldId(objectDefinition, descriptionObjectFieldId);
_validateObjectFieldId(objectDefinition, titleObjectFieldId);
_validateActive(active, status);
if (Validator.isNull(oldClassName)) {
_validateClassName(
objectDefinition.getObjectDefinitionId(),
objectDefinition.getCompanyId(), className,
objectDefinition.isModifiable(), objectDefinition.isSystem());
}
_validateEnableCategorization(
enableCategorization, objectDefinition.isModifiable(),
objectDefinition.getStorageType(), objectDefinition.isSystem());
_validateEnableComments(
enableComments, objectDefinition.isModifiable(),
objectDefinition.getStorageType(), objectDefinition.isSystem());
_validateEnableObjectEntryHistory(
objectDefinition.isEnableObjectEntryHistory() !=
enableObjectEntryHistory,
objectDefinition.isModifiable(), objectDefinition.getStorageType(),
objectDefinition.isSystem());
_validateLabel(labelMap);
_validatePluralLabel(pluralLabelMap);
if (objectDefinition.getAccountEntryRestrictedObjectFieldId() != 0) {
_objectFieldLocalService.updateRequired(
objectDefinition.getAccountEntryRestrictedObjectFieldId(),
false);
}
if (accountEntryRestricted &&
(accountEntryRestrictedObjectFieldId > 0)) {
_objectFieldLocalService.updateRequired(
accountEntryRestrictedObjectFieldId, true);
}
objectDefinition.setExternalReferenceCode(externalReferenceCode);
objectDefinition.setAccountEntryRestrictedObjectFieldId(
accountEntryRestrictedObjectFieldId);
objectDefinition.setDescriptionObjectFieldId(descriptionObjectFieldId);
objectDefinition.setObjectFolderId(
_getObjectFolderId(
objectDefinition.getCompanyId(), objectFolderId));
objectDefinition.setTitleObjectFieldId(titleObjectFieldId);
objectDefinition.setAccountEntryRestricted(accountEntryRestricted);
objectDefinition.setActive(active);
if (Validator.isNull(oldClassName)) {
objectDefinition.setClassName(
_getClassName(
objectDefinition.getCompanyId(), className,
objectDefinition.isModifiable(),
objectDefinition.isSystem()));
}
objectDefinition.setEnableCategorization(enableCategorization);
objectDefinition.setEnableComments(enableComments);
objectDefinition.setEnableObjectEntryDraft(enableObjectEntryDraft);
objectDefinition.setEnableObjectEntryHistory(enableObjectEntryHistory);
objectDefinition.setLabelMap(labelMap, LocaleUtil.getSiteDefault());
objectDefinition.setPanelAppOrder(panelAppOrder);
objectDefinition.setPanelCategoryKey(panelCategoryKey);
objectDefinition.setPluralLabelMap(pluralLabelMap);
objectDefinition.setPortlet(portlet);
if (!objectDefinition.isUnmodifiableSystemObject()) {
_addOrUpdateObjectDefinitionPLOEntries(objectDefinition);
}
if (objectDefinition.isApproved()) {
if (!active && oldActive) {
objectDefinitionLocalService.deployInactiveObjectDefinition(
objectDefinition);
}
else if (active) {
objectDefinitionLocalService.deployObjectDefinition(
objectDefinition);
}
if (active != oldActive) {
_updateWorkflowInstances(objectDefinition);
}
objectDefinition = objectDefinitionPersistence.update(
objectDefinition);
_objectFolderItemLocalService.updateObjectFolderObjectFolderItem(
objectDefinition.getObjectDefinitionId(),
objectDefinition.getObjectFolderId(), oldObjectFolderId);
return objectDefinition;
}
name = _getName(name, objectDefinition.isSystem());
String shortName = ObjectDefinitionImpl.getShortName(name);
dbTableName = _getDBTableName(
dbTableName, objectDefinition.isModifiable(), name,
objectDefinition.isSystem(), objectDefinition.getCompanyId(),
shortName);
pkObjectFieldName = _getPKObjectFieldName(
pkObjectFieldName, objectDefinition.isModifiable(),
objectDefinition.isSystem(), shortName);
pkObjectFieldDBColumnName = _getPKObjectFieldDBColumnName(
pkObjectFieldDBColumnName, pkObjectFieldName,
objectDefinition.isModifiable(), objectDefinition.isSystem());
_validateName(
objectDefinition.getObjectDefinitionId(),
objectDefinition.getCompanyId(), objectDefinition.isModifiable(),
name, objectDefinition.isSystem());
_validateScope(scope, objectDefinition.getStorageType());
objectDefinition.setDBTableName(dbTableName);
objectDefinition.setEnableIndexSearch(enableIndexSearch);
objectDefinition.setEnableLocalization(enableLocalization);
objectDefinition.setName(name);
objectDefinition.setPKObjectFieldDBColumnName(
pkObjectFieldDBColumnName);
objectDefinition.setPKObjectFieldName(pkObjectFieldName);
objectDefinition.setScope(scope);
objectDefinition = objectDefinitionPersistence.update(objectDefinition);
for (ObjectField objectField :
_objectFieldLocalService.getObjectFields(
objectDefinition.getObjectDefinitionId(),
StringPool.BLANK)) {
objectField.setDBTableName(objectDefinition.getDBTableName());
_objectFieldLocalService.updateObjectField(objectField);
}
_objectFolderItemLocalService.updateObjectFolderObjectFolderItem(
objectDefinition.getObjectDefinitionId(),
objectDefinition.getObjectFolderId(), oldObjectFolderId);
return objectDefinition;
}
private ObjectDefinition _updateTitleObjectFieldId(
ObjectDefinition objectDefinition, String titleObjectFieldName)
throws PortalException {
if (Validator.isNull(titleObjectFieldName)) {
titleObjectFieldName = "id";
}
ObjectField objectField = _objectFieldPersistence.findByODI_N(
objectDefinition.getObjectDefinitionId(), titleObjectFieldName);
_validateObjectFieldId(
objectDefinition, objectField.getObjectFieldId());
objectDefinition.setTitleObjectFieldId(objectField.getObjectFieldId());
return objectDefinitionPersistence.update(objectDefinition);
}
private void _updateWorkflowInstances(ObjectDefinition objectDefinition)
throws PortalException {
ActionableDynamicQuery actionableDynamicQuery =
_objectEntryLocalService.getActionableDynamicQuery();
actionableDynamicQuery.setAddCriteriaMethod(
dynamicQuery -> {
Property objectDefinitionIdProperty =
PropertyFactoryUtil.forName("objectDefinitionId");
dynamicQuery.add(
objectDefinitionIdProperty.eq(
objectDefinition.getObjectDefinitionId()));
Property statusProperty = PropertyFactoryUtil.forName("status");
dynamicQuery.add(
statusProperty.ne(WorkflowConstants.STATUS_APPROVED));
});
actionableDynamicQuery.setParallel(true);
actionableDynamicQuery.setPerformActionMethod(
(ObjectEntry objectEntry) -> {
WorkflowInstanceLink workflowInstanceLink =
_workflowInstanceLinkLocalService.fetchWorkflowInstanceLink(
objectEntry.getCompanyId(),
objectEntry.getNonzeroGroupId(),
objectDefinition.getClassName(),
objectEntry.getObjectEntryId());
if (workflowInstanceLink != null) {
_workflowInstanceManager.updateActive(
objectDefinition.getUserId(),
objectDefinition.getCompanyId(),
workflowInstanceLink.getWorkflowInstanceId(),
objectDefinition.isActive());
}
});
actionableDynamicQuery.performActions();
}
private void _validateAccountEntryRestrictedObjectFieldId(
long accountEntryRestrictedObjectFieldId,
boolean accountEntryRestricted, ObjectDefinition objectDefinition)
throws ObjectDefinitionAccountEntryRestrictedException,
ObjectDefinitionAccountEntryRestrictedObjectFieldIdException {
if (accountEntryRestricted &&
(accountEntryRestrictedObjectFieldId == 0)) {
throw new ObjectDefinitionAccountEntryRestrictedObjectFieldIdException();
}
if (objectDefinition.isApproved() &&
objectDefinition.isAccountEntryRestricted() &&
!accountEntryRestricted) {
throw new ObjectDefinitionAccountEntryRestrictedException(
"Account entry restriction cannot be disabled when the " +
"object definition is published");
}
}
private void _validateActive(boolean active, int status)
throws PortalException {
if (active &&
!Objects.equals(WorkflowConstants.STATUS_APPROVED, status)) {
throw new ObjectDefinitionActiveException(
"Object definitions must be published before being activated");
}
}
private void _validateClassName(
long objectDefinitionId, long companyId, String className,
boolean modifiable, boolean system)
throws PortalException {
if (Validator.isNull(className) ||
_isUnmodifiableSystemObject(modifiable, system)) {
return;
}
ObjectDefinition existingObjectDefinition =
objectDefinitionPersistence.fetchByC_C(companyId, className);
if ((existingObjectDefinition != null) &&
(existingObjectDefinition.getObjectDefinitionId() !=
objectDefinitionId)) {
throw new ObjectDefinitionClassNameException.MustNotBeDuplicate(
className);
}
if (!StringUtil.startsWith(
className,
ObjectDefinitionConstants.
CLASS_NAME_PREFIX_CUSTOM_OBJECT_DEFINITION)) {
throw new ObjectDefinitionClassNameException.MustStartWithPrefix();
}
}
private void _validateEnableCategorization(
boolean enableCategorization, boolean modifiable,
String storageType, boolean system)
throws PortalException {
if (enableCategorization &&
_isUnmodifiableSystemObject(modifiable, system)) {
throw new ObjectDefinitionEnableCategorizationException(
"Enable categorization is not allowed for system object " +
"definitions");
}
if (enableCategorization &&
!StringUtil.equals(
storageType, ObjectDefinitionConstants.STORAGE_TYPE_DEFAULT)) {
throw new ObjectDefinitionEnableCategorizationException(
"Enable categorization is only allowed for object " +
"definitions with the default storage type");
}
}
private void _validateEnableComments(
boolean enableComments, boolean modifiable, String storageType,
boolean system)
throws PortalException {
if (enableComments && _isUnmodifiableSystemObject(modifiable, system)) {
throw new ObjectDefinitionEnableCommentsException(
"Enable comments is not allowed for system object definitions");
}
if (enableComments &&
!StringUtil.equals(
storageType, ObjectDefinitionConstants.STORAGE_TYPE_DEFAULT)) {
throw new ObjectDefinitionEnableCategorizationException(
"Enable comments is only allowed for object definitions with " +
"the default storage type");
}
}
private void _validateEnableObjectEntryHistory(
boolean enableObjectEntryHistoryChanged, boolean modifiable,
String storageType, boolean system)
throws PortalException {
if (!enableObjectEntryHistoryChanged) {
return;
}
if (_isUnmodifiableSystemObject(modifiable, system)) {
throw new ObjectDefinitionEnableObjectEntryHistoryException(
"Enable object entry history is not allowed for system " +
"object definitions");
}
if (!StringUtil.equals(
storageType, ObjectDefinitionConstants.STORAGE_TYPE_DEFAULT)) {
throw new ObjectDefinitionEnableObjectEntryHistoryException(
"Enable object entry history is only allowed for object " +
"definitions with the default storage type");
}
}
private void _validateExternalReferenceCode(
String externalReferenceCode, boolean system)
throws PortalException {
if (Validator.isNull(externalReferenceCode)) {
return;
}
char[] externalReferenceCodeCharArray =
externalReferenceCode.toCharArray();
if (externalReferenceCodeCharArray.length > 75) {
throw new ObjectDefinitionExternalReferenceCodeException.
MustBeLessThan75Characters();
}
if (!system &&
externalReferenceCode.startsWith(
ObjectDefinitionConstants.
EXTERNAL_REFERENCE_CODE_PREFIX_SYSTEM_OBJECT_DEFINITION)) {
throw new ObjectDefinitionExternalReferenceCodeException.
MustNotStartWithPrefix();
}
}
private void _validateLabel(Map labelMap)
throws PortalException {
Locale locale = LocaleUtil.getSiteDefault();
if ((labelMap == null) || Validator.isNull(labelMap.get(locale))) {
throw new ObjectDefinitionLabelException(
"Label is null for locale " + locale.getDisplayName());
}
}
private void _validateName(
long objectDefinitionId, long companyId, boolean modifiable,
String name, boolean system)
throws PortalException {
if (modifiable && system &&
!ObjectDefinitionUtil.isAllowedModifiableSystemObjectDefinitionName(
name)) {
throw new ObjectDefinitionNameException.
ForbiddenModifiableSystemObjectDefinitionName(name);
}
if (Validator.isNull(name) || (!system && name.equals("C_"))) {
throw new ObjectDefinitionNameException.MustNotBeNull();
}
if (_isUnmodifiableSystemObject(modifiable, system) &&
(name.startsWith("C_") || name.startsWith("c_"))) {
throw new ObjectDefinitionNameException.
MustNotStartWithCAndUnderscoreForSystemObject();
}
else if (!system && !name.startsWith("C_")) {
throw new ObjectDefinitionNameException.
MustStartWithCAndUnderscoreForCustomObject();
}
char[] nameCharArray = name.toCharArray();
for (int i = 0; i < nameCharArray.length; i++) {
if (modifiable || !system) {
// Skip C_
if ((i == 0) || (i == 1)) {
continue;
}
}
char c = nameCharArray[i];
if (!Validator.isChar(c) && !Validator.isDigit(c)) {
throw new ObjectDefinitionNameException.
MustOnlyContainLettersAndDigits();
}
}
if ((system && !Character.isUpperCase(nameCharArray[0])) ||
(!system && !Character.isUpperCase(nameCharArray[2]))) {
throw new ObjectDefinitionNameException.
MustBeginWithUpperCaseLetter();
}
if ((system && (nameCharArray.length > 41)) ||
(!system && (nameCharArray.length > 43))) {
throw new ObjectDefinitionNameException.
MustBeLessThan41Characters();
}
ObjectDefinition objectDefinition =
objectDefinitionPersistence.fetchByC_N(companyId, name);
if ((objectDefinition != null) &&
(objectDefinition.getObjectDefinitionId() != objectDefinitionId)) {
throw new ObjectDefinitionNameException.MustNotBeDuplicate(name);
}
}
private void _validateObjectFieldId(
ObjectDefinition objectDefinition, long objectFieldId)
throws PortalException {
if (objectFieldId <= 0) {
return;
}
ObjectField objectField = _objectFieldLocalService.fetchObjectField(
objectFieldId);
if ((objectField == null) ||
(objectField.getObjectDefinitionId() !=
objectDefinition.getObjectDefinitionId())) {
throw new NoSuchObjectFieldException();
}
if (Validator.isNotNull(objectField.getRelationshipType())) {
throw new ObjectFieldRelationshipTypeException(
"Description and title object fields cannot have a " +
"relationship type");
}
}
private void _validatePluralLabel(Map pluralLabelMap)
throws PortalException {
Locale locale = LocaleUtil.getSiteDefault();
if ((pluralLabelMap == null) ||
Validator.isNull(pluralLabelMap.get(locale))) {
throw new ObjectDefinitionPluralLabelException(
"Plural label is null for locale " + locale.getDisplayName());
}
}
private void _validateScope(String scope, String storageType)
throws PortalException {
if (Validator.isNull(scope)) {
throw new ObjectDefinitionScopeException("Scope is null");
}
try {
_objectScopeProviderRegistry.getObjectScopeProvider(scope);
}
catch (IllegalArgumentException illegalArgumentException) {
throw new ObjectDefinitionScopeException(
illegalArgumentException.getMessage());
}
if (StringUtil.equals(scope, ObjectDefinitionConstants.SCOPE_SITE) &&
StringUtil.equals(
storageType,
ObjectDefinitionConstants.STORAGE_TYPE_SALESFORCE)) {
throw new ObjectDefinitionScopeException(
StringBundler.concat(
"Scope \"", ObjectDefinitionConstants.SCOPE_SITE,
"\" cannot be associated with storage type \"",
ObjectDefinitionConstants.STORAGE_TYPE_SALESFORCE));
}
}
private void _validateVersion(boolean system, int version)
throws PortalException {
if (system) {
if (version <= 0) {
throw new ObjectDefinitionVersionException(
"System object definition versions must greater than 0");
}
}
else {
if (version != 0) {
throw new ObjectDefinitionVersionException(
"Custom object definition versions must be 0");
}
}
}
private static final Log _log = LogFactoryUtil.getLog(
ObjectDefinitionLocalServiceImpl.class);
private static final MethodKey _deployObjectDefinitionMethodKey =
new MethodKey(
ObjectDefinitionLocalServiceUtil.class, "deployObjectDefinition",
ObjectDefinition.class);
private static final MethodKey _undeployObjectDefinitionMethodKey =
new MethodKey(
ObjectDefinitionLocalServiceUtil.class, "undeployObjectDefinition",
ObjectDefinition.class);
@Reference
private AccountEntryLocalService _accountEntryLocalService;
@Reference
private AccountEntryOrganizationRelLocalService
_accountEntryOrganizationRelLocalService;
@Reference
private AssetEntryLocalService _assetEntryLocalService;
private BundleContext _bundleContext;
@Reference
private ClassNameLocalService _classNameLocalService;
@Reference
private CompanyLocalService _companyLocalService;
@Reference
private CurrentConnection _currentConnection;
@Reference
private DynamicQueryBatchIndexingActionableFactory
_dynamicQueryBatchIndexingActionableFactory;
@Reference
private FragmentEntryLinkCache _fragmentEntryLinkCache;
@Reference
private GroupLocalService _groupLocalService;
private final Map
>>>
_inactiveObjectDefinitionsServiceRegistrationsMaps =
Collections.synchronizedMap(new LinkedHashMap<>());
@Reference
private Language _language;
@Reference
private LayoutClassedModelUsageLocalService
_layoutClassedModelUsageLocalService;
@Reference
private ListTypeLocalService _listTypeLocalService;
@Reference
private ObjectActionLocalService _objectActionLocalService;
private ServiceTracker
_objectDefinitionDeployerServiceTracker;
@Reference
private ObjectEntryLocalService _objectEntryLocalService;
@Reference
private ObjectEntryPersistence _objectEntryPersistence;
@Reference
private ObjectEntryService _objectEntryService;
@Reference
private ObjectFieldLocalService _objectFieldLocalService;
@Reference
private ObjectFieldPersistence _objectFieldPersistence;
@Reference
private ObjectFolderItemLocalService _objectFolderItemLocalService;
@Reference
private ObjectFolderLocalService _objectFolderLocalService;
@Reference
private ObjectFolderPersistence _objectFolderPersistence;
@Reference
private ObjectLayoutLocalService _objectLayoutLocalService;
@Reference
private ObjectLayoutTabLocalService _objectLayoutTabLocalService;
@Reference
private ObjectRelatedModelsProviderRegistrarHelper
_objectRelatedModelsProviderRegistrarHelper;
@Reference
private ObjectRelationshipLocalService _objectRelationshipLocalService;
@Reference
private ObjectRelationshipPersistence _objectRelationshipPersistence;
@Reference
private ObjectScopeProviderRegistry _objectScopeProviderRegistry;
@Reference
private ObjectValidationRuleLocalService _objectValidationRuleLocalService;
@Reference
private ObjectViewLocalService _objectViewLocalService;
@Reference
private OrganizationLocalService _organizationLocalService;
@Reference
private PLOEntryLocalService _ploEntryLocalService;
@Reference
private Portal _portal;
@Reference
private PortletLocalService _portletLocalService;
@Reference
private ResourceActions _resourceActions;
@Reference
private ResourceLocalService _resourceLocalService;
@Reference
private ResourcePermissionLocalService _resourcePermissionLocalService;
@Reference
private ResourcePermissionPersistence _resourcePermissionPersistence;
@Reference
private SearchLocalizationHelper _searchLocalizationHelper;
private final Map
>>>
_serviceRegistrationsMaps = Collections.synchronizedMap(
new LinkedHashMap<>());
@Reference
private UserGroupRoleLocalService _userGroupRoleLocalService;
@Reference
private UserLocalService _userLocalService;
@Reference
private WorkflowInstanceLinkLocalService _workflowInstanceLinkLocalService;
@Reference
private WorkflowInstanceManager _workflowInstanceManager;
@Reference(target = "(model.pre.filter.contributor.id=WorkflowStatus)")
private ModelPreFilterContributor _workflowStatusModelPreFilterContributor;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy