diff --git a/src/main/api/studio-api.yaml b/src/main/api/studio-api.yaml index 82b99d0979..637a3244e5 100644 --- a/src/main/api/studio-api.yaml +++ b/src/main/api/studio-api.yaml @@ -66,6 +66,10 @@ tags: description: Server operations - name: system description: System operations + - name: model + description: Data models definitions + - name: contentTypes + description: Content type operations paths: @@ -2437,55 +2441,6 @@ paths: '401': $ref: '#/components/responses/Unauthorized' - /api/1/services/api/1/content/get-pages.json: - get: - tags: - - content - summary: Get pages. Gets tree of content items for given path. - description: "Required role: N/A" - operationId: getPages - parameters: - - name: site_id - in: query - description: Project/Site ID to use - required: true - schema: - type: string - - name: path - in: query - schema: - type: string - description: Path of the content - required: true - example: /site/website/index.xml - - name: depth - in: query - schema: - type: integer - description: Depth of the tree to display - required: true - example: 1 - - name: order - in: query - schema: - type: string - description: Order of content items. - required: true - example: default - responses: - '200': - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/ContentItemV1' - '400': - $ref: '#/components/responses/api1BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - /api/1/services/api/1/content/reorder-items.json: get: tags: @@ -3787,7 +3742,7 @@ paths: properties: response: $ref: '#/components/schemas/ApiResponse' - dependencies: + usage: type: object properties: templates: @@ -10681,8 +10636,6 @@ components: type: string form: type: string - formPagePath: - type: string renderingTemplates: type: array items: diff --git a/src/main/java/org/craftercms/studio/api/v1/aws/mediaconvert/MediaConvert.java b/src/main/java/org/craftercms/studio/api/v1/aws/mediaconvert/MediaConvert.java deleted file mode 100644 index 9e4bc3a019..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/aws/mediaconvert/MediaConvert.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.aws.mediaconvert; - -import java.io.InputStream; - -import org.craftercms.studio.api.v1.exception.AwsException; - -/** - * Defines the operations available for AWS MediaConvert. - * - * @author joseross - */ -public interface MediaConvert { - - /** - * Uploads a file to AWS S3 and starts a transcoding job in AWS MediaConvert. - * - * @param filename name of the file to upload - * @param content stream providing the content of the file to upload - * @param profile profile used to create the transcoding job - * @return information of the transcoding job - * @throws AwsException if the upload or transcoding job creation fails - */ - MediaConvertJob startJob(String filename, InputStream content, MediaConvertProfile profile) throws AwsException; - -} diff --git a/src/main/java/org/craftercms/studio/api/v1/dal/DependencyMapper.java b/src/main/java/org/craftercms/studio/api/v1/dal/DependencyMapper.java deleted file mode 100644 index f06d80d141..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/dal/DependencyMapper.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.dal; - -import java.util.List; -import java.util.Map; - -/** - * @author Dejan Brkic - */ -public interface DependencyMapper { - - String SITE_PARAM = "site"; - String PATHS_PARAM = "paths"; - String REGEX_PARAM = "regex"; - - List getDependenciesForList(Map params); - - List getItemSpecificDependenciesForList(Map params); - - @Deprecated - List getItemsDependingOn(Map params); -} diff --git a/src/main/java/org/craftercms/studio/api/v1/dal/GroupPerSiteResult.java b/src/main/java/org/craftercms/studio/api/v1/dal/GroupPerSiteResult.java deleted file mode 100644 index 9eb72f5067..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/dal/GroupPerSiteResult.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.dal; - -public class GroupPerSiteResult { - - protected String groupName; - protected String groupDescription; - protected String username; - protected String firstName; - protected String lastName; - protected String email; - protected int externallyManaged; - - public String getGroupName() { - return groupName; - } - - public void setGroupName(String groupName) { - this.groupName = groupName; - } - - public String getGroupDescription() { - return groupDescription; - } - - public void setGroupDescription(String groupDescription) { - this.groupDescription = groupDescription; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public int getExternallyManaged() { - return externallyManaged; - } - - public void setExternallyManaged(int externallyManaged) { - this.externallyManaged = externallyManaged; - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/dal/GroupResult.java b/src/main/java/org/craftercms/studio/api/v1/dal/GroupResult.java deleted file mode 100644 index aa66701a1c..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/dal/GroupResult.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.dal; - -public class GroupResult { - - private String siteId; - private String siteName; - private String groupName; - private String groupDescription; - - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - - public String getSiteName() { - return siteName; - } - - public void setSiteName(String siteName) { - this.siteName = siteName; - } - - public String getGroupName() { - return groupName; - } - - public void setGroupName(String groupName) { - this.groupName = groupName; - } - - public String getGroupDescription() { - return groupDescription; - } - - public void setGroupDescription(String groupDescription) { - this.groupDescription = groupDescription; - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/dal/Permission.java b/src/main/java/org/craftercms/studio/api/v1/dal/Permission.java deleted file mode 100644 index 32cf4b704f..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/dal/Permission.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.dal; - -import java.io.Serializable; - -public class Permission implements Serializable { - - private static final long serialVersionUID = 7657923215314010507L; - - private long id; - private String name; - private String description; - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/dal/Role.java b/src/main/java/org/craftercms/studio/api/v1/dal/Role.java deleted file mode 100644 index 3b20398e1c..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/dal/Role.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.dal; - -import java.io.Serializable; -import java.util.List; - -public class Role implements Serializable { - - private static final long serialVersionUID = -8621678155190259891L; - - private long id; - private String name; - private String description; - - private List permissionIds; - private List permissions; - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public List getPermissionIds() { - return permissionIds; - } - - public void setPermissionIds(List permissionIds) { - this.permissionIds = permissionIds; - } - - public List getPermissions() { - return permissions; - } - - public void setPermissions(List permissions) { - this.permissions = permissions; - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/dal/SiteFeed.java b/src/main/java/org/craftercms/studio/api/v1/dal/SiteFeed.java deleted file mode 100644 index 25918c36f6..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/dal/SiteFeed.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.dal; - -@Deprecated -public class SiteFeed { - - public static final String STATE_INITIALIZING = "INITIALIZING"; - public static final String STATE_LOCKED = "LOCKED"; - public static final String STATE_READY = "READY"; - public static final String STATE_DELETING = "DELETING"; - public static final String STATE_DELETED = "DELETED"; - - protected long id; - protected String siteUuid; - protected String siteId; - protected String name; - protected String description; - protected int deleted; - protected String liveUrl; - protected int publishingEnabled; - protected String publishingStatus; - protected String sandboxBranch; - protected int publishedRepoCreated; - protected String state; - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getSiteUuid() { - return siteUuid; - } - - public void setSiteUuid(String siteUuid) { - this.siteUuid = siteUuid; - } - - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getLiveUrl() { - return liveUrl; - } - - public void setLiveUrl(String liveUrl) { - this.liveUrl = liveUrl; - } - - public int getPublishingEnabled() { - return publishingEnabled; - } - - public void setPublishingEnabled(int publishingEnabled) { - this.publishingEnabled = publishingEnabled; - } - - public String getPublishingStatus() { - return publishingStatus; - } - - public void setPublishingStatus(String publishingStatus) { - this.publishingStatus = publishingStatus; - } - - public String getSandboxBranch() { - return sandboxBranch; - } - - public void setSandboxBranch(String sandboxBranch) { - this.sandboxBranch = sandboxBranch; - } - - public int getDeleted() { - return deleted; - } - - public void setDeleted(int deleted) { - this.deleted = deleted; - } - - public boolean isSiteDeleted() { - return deleted != 0; - } - - public int getPublishedRepoCreated() { - return publishedRepoCreated; - } - - public void setPublishedRepoCreated(int publishedRepoCreated) { - this.publishedRepoCreated = publishedRepoCreated; - } - - public boolean isSitePublishedRepoCreated() { - return publishedRepoCreated > 0; - } - - public String getState() { - return state; - } - - public void setState(String state) { - this.state = state; - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/dal/SiteFeedMapper.java b/src/main/java/org/craftercms/studio/api/v1/dal/SiteFeedMapper.java deleted file mode 100644 index a65078f331..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/dal/SiteFeedMapper.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.dal; - -import org.apache.ibatis.annotations.Param; - -import java.util.List; -import java.util.Map; - -import static org.craftercms.studio.api.v2.dal.QueryParameterNames.*; - -public interface SiteFeedMapper { - - Integer exists(String siteId); - - /** - * Checks if there is a site, different than the siteId, using the given name - * - * @param siteId the id of the site - * @param name the name of the site - * @return true if the name is being used by another site - */ - boolean isNameUsed(@Param(SITE_ID) String siteId, @Param(NAME) String name); - - int getSitesPerUserQueryTotal(Map params); - - List getSitesPerUserQuery(Map params); - - List getSitesPerUserData(Map params); - - /** - * Updates the name and description for the given site - * - * @param siteId the id of the site - * @param name the name of the site - * @param description the description of the site - * @return the number of changed rows - */ - int updateSite(@Param(SITE_ID) String siteId, @Param(NAME) String name, @Param(DESC) String description); - -} diff --git a/src/main/java/org/craftercms/studio/api/v1/dal/UserProfileResult.java b/src/main/java/org/craftercms/studio/api/v1/dal/UserProfileResult.java deleted file mode 100644 index 351b7b4750..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/dal/UserProfileResult.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.dal; - -public class UserProfileResult { - - protected String username; - protected String lastName; - protected String firstName; - protected String email; - protected String groupName; - protected String siteId; - protected String siteName; - protected int externallyManaged; - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getGroupName() { - return groupName; - } - - public void setGroupName(String groupName) { - this.groupName = groupName; - } - - public String getSiteId() { - return siteId; - } - - public void setSiteId(String siteId) { - this.siteId = siteId; - } - - public String getSiteName() { - return siteName; - } - - public void setSiteName(String siteName) { - this.siteName = siteName; - } - - public int getExternallyManaged() { - return externallyManaged; - } - - public void setExternallyManaged(int externallyManaged) { - this.externallyManaged = externallyManaged; - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/exception/EnvironmentNotFoundException.java b/src/main/java/org/craftercms/studio/api/v1/exception/EnvironmentNotFoundException.java deleted file mode 100644 index 90af5d4afc..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/exception/EnvironmentNotFoundException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.exception; - -public class EnvironmentNotFoundException extends ServiceLayerException { - - private static final long serialVersionUID = 6176134353135084107L; - - public EnvironmentNotFoundException() { - } - - public EnvironmentNotFoundException(Exception e) { - super(e); - } - - public EnvironmentNotFoundException(String message) { - super(message); - } - - public EnvironmentNotFoundException(String message, Exception e) { - super(message, e); - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/service/AbstractRegistrableService.java b/src/main/java/org/craftercms/studio/api/v1/service/AbstractRegistrableService.java deleted file mode 100644 index 566b1fd82f..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/service/AbstractRegistrableService.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.service; - - -public abstract class AbstractRegistrableService { - - protected ServicesManager _servicesManager; - - public ServicesManager getServicesManager() { - return _servicesManager; - } - - public void setServicesManager(ServicesManager servicesManager) { - this._servicesManager = servicesManager; - } - - public abstract void register(); - - public T getService(Class type) { - return this._servicesManager.getService(type); - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/service/ServicesManager.java b/src/main/java/org/craftercms/studio/api/v1/service/ServicesManager.java deleted file mode 100644 index 4864a34b3f..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/service/ServicesManager.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.service; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashMap; -import java.util.Map; - -public class ServicesManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(ServicesManager.class); - - protected Map _servicesMap = new HashMap<>(); - - public Map getServicesMap() { - return _servicesMap; - } - - public void setServicesMap(Map servicesMap) { - this._servicesMap = servicesMap; - } - - public void registerService(Class clazz, Object service) { - if (_servicesMap == null) { - _servicesMap = new HashMap<>(); - } - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Registering service: " + clazz.getName()); - } - _servicesMap.put(clazz, service); - } - - public T getService(Class clazz) { - return clazz.cast(_servicesMap.get(clazz)); - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/service/asset/processing/AssetProcessingService.java b/src/main/java/org/craftercms/studio/api/v1/service/asset/processing/AssetProcessingService.java deleted file mode 100644 index d5e1a48ffe..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/service/asset/processing/AssetProcessingService.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.service.asset.processing; - -import org.craftercms.commons.validation.ValidationException; - -import java.io.InputStream; -import java.util.Map; - -/** - * Service to run an asset through processor pipelines. Asset processing can be used to perform image transformation like - * ImageMagick and Tinify. - * - * @author avasquez - */ -public interface AssetProcessingService { - - Map processAsset(String site, String path, String assetName, InputStream in, String isImage, - String allowedWidth, String allowedHeight, String allowLessSize, String draft, - String unlock, String systemAsset) throws ValidationException; - -} diff --git a/src/main/java/org/craftercms/studio/api/v1/service/aws/ElasticTranscoderService.java b/src/main/java/org/craftercms/studio/api/v1/service/aws/ElasticTranscoderService.java deleted file mode 100644 index 759a0983c3..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/service/aws/ElasticTranscoderService.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.service.aws; - -import java.io.InputStream; - -import org.craftercms.commons.config.profiles.ConfigurationProfileNotFoundException; -import org.craftercms.studio.api.v1.aws.elastictranscoder.TranscoderJob; -import org.craftercms.studio.api.v1.exception.AwsException; - -/** - * Service that provides access to the AWS Elastic Transcoder to sites for video transcoding. - * - * @author avasquez - */ -public interface ElasticTranscoderService { - - /** - * Requests the transcoding of the specified file to the AWS Elastic Transcoder, using the specified - * {@link org.craftercms.studio.api.v1.aws.elastictranscoder.TranscoderProfile}. - * - * @param site the site - * @param profileId the id of the {@link org.craftercms.studio.api.v1.aws.elastictranscoder.TranscoderProfile} to use - * @param filename the name of the video file to transcode - * @param content the video file itself - * @return the {@link TranscoderJob} that was started - * @throws AwsException if an error occurs - */ - TranscoderJob transcodeFile(String site, String profileId, String filename, InputStream content) throws - AwsException, ConfigurationProfileNotFoundException; - -} diff --git a/src/main/java/org/craftercms/studio/api/v1/service/aws/MediaConvertService.java b/src/main/java/org/craftercms/studio/api/v1/service/aws/MediaConvertService.java deleted file mode 100644 index fad3ebd7d2..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/service/aws/MediaConvertService.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.service.aws; - -import java.io.InputStream; - -import org.craftercms.commons.config.profiles.ConfigurationProfileNotFoundException; -import org.craftercms.studio.api.v1.aws.mediaconvert.MediaConvertJob; -import org.craftercms.studio.api.v1.exception.AwsException; - -/** - * Defines the operations available from AWS MediaConvert. - * - * @author joseross - * @deprecated This service has been replaced with - * {@link org.craftercms.studio.api.v2.service.aws.mediaconvert.AwsMediaConvertService} - */ -@Deprecated -public interface MediaConvertService { - - /** - * Uploads a file to S3 and creates a transcoding job using the specified profile. - * - * @param site name of the site - * @param profileId id of the profile - * @param filename name of the file - * @param content content of the file - * @return information of the transcoding job - * @throws AwsException if the upload or transcoding job creation fails - * @throws ConfigurationProfileNotFoundException if the profile is not found - */ - MediaConvertJob startJob(String site, String profileId, String filename, InputStream content) throws AwsException, ConfigurationProfileNotFoundException; - -} diff --git a/src/main/java/org/craftercms/studio/api/v1/service/aws/S3Service.java b/src/main/java/org/craftercms/studio/api/v1/service/aws/S3Service.java deleted file mode 100644 index ac97422367..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/service/aws/S3Service.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.service.aws; - -import java.io.InputStream; - -import org.craftercms.commons.config.profiles.ConfigurationProfileNotFoundException; -import org.craftercms.studio.api.v1.aws.s3.S3Output; -import org.craftercms.studio.api.v1.exception.AwsException; - -/** - * Service that provides access to AWS S3 to upload files. - * - * @author joseross - * @deprecated This service has been replaced with {@link org.craftercms.studio.api.v2.service.aws.s3.AwsS3Service} - */ -@Deprecated -public interface S3Service { - - /** - * Requests the file upload using the specified {@link org.craftercms.commons.config.profiles.aws.S3Profile}. - * - * @param site the site - * @param profileId the id of the {@link org.craftercms.commons.config.profiles.aws.S3Profile} to use. - * @param filename the name of the file to upload - * @param content the file itself - * @return metadata of an AWS S3 upload - * @throws AwsException if an error occurs - * @throws ConfigurationProfileNotFoundException if the profile is not found - */ - S3Output uploadFile(String site, String profileId, String filename, InputStream content) throws AwsException, ConfigurationProfileNotFoundException; - -} diff --git a/src/main/java/org/craftercms/studio/api/v1/service/configuration/ContentTypesConfig.java b/src/main/java/org/craftercms/studio/api/v1/service/configuration/ContentTypesConfig.java deleted file mode 100644 index 878dafa9e7..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/service/configuration/ContentTypesConfig.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.service.configuration; - -import org.craftercms.studio.api.v1.exception.SiteNotFoundException; -import org.craftercms.studio.api.v1.to.ContentTypeConfigTO; - -/** - * provides content type configuration - * - * @author hyanghee - */ -public interface ContentTypesConfig { - - /** - * get content type configuration for the given site and the content type - * - * @param site - * @param contentType - * @return content type configuration - */ - ContentTypeConfigTO getContentTypeConfig(String site, String contentType) throws SiteNotFoundException; - - /** - * load configuration from the noderRef given - * - * @param site - * @param contentType - * @return content type configuration - */ - ContentTypeConfigTO loadConfiguration(String site, String contentType) throws SiteNotFoundException; - - ContentTypeConfigTO reloadConfiguration(String site, String contentType) throws SiteNotFoundException; - -} diff --git a/src/main/java/org/craftercms/studio/api/v1/service/configuration/ServicesConfig.java b/src/main/java/org/craftercms/studio/api/v1/service/configuration/ServicesConfig.java index 77358c7a71..8f23c85596 100644 --- a/src/main/java/org/craftercms/studio/api/v1/service/configuration/ServicesConfig.java +++ b/src/main/java/org/craftercms/studio/api/v1/service/configuration/ServicesConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -17,8 +17,6 @@ import org.craftercms.studio.api.v1.exception.SiteNotFoundException; import org.craftercms.studio.api.v1.to.ContentMonitorConfigTO; -import org.craftercms.studio.api.v1.to.ContentTypeConfigTO; -import org.craftercms.studio.api.v1.to.CopyDependencyConfigTO; import org.craftercms.studio.api.v1.to.FacetTO; import java.util.List; @@ -31,15 +29,6 @@ */ public interface ServicesConfig { - /** - * get DM content type configuration by the given site and name - * - * @param site - * @param name - * @return content type - */ - ContentTypeConfigTO getContentTypeConfig(String site, String name) throws SiteNotFoundException; - /** * get component item URI patterns * @@ -105,15 +94,6 @@ public interface ServicesConfig { */ String getLevelDescriptorName(String site) throws SiteNotFoundException; - /** - * get the copy dependencies pattern for a content type - * - * @param site - * @param contentType - * @return copy dependencies patterns - */ - List getCopyDependencyPatterns(String site, String contentType) throws SiteNotFoundException; - /** * get the default timezone value * diff --git a/src/main/java/org/craftercms/studio/api/v1/service/content/ContentItemIdGenerator.java b/src/main/java/org/craftercms/studio/api/v1/service/content/ContentItemIdGenerator.java deleted file mode 100644 index 22fee32e7a..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/service/content/ContentItemIdGenerator.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.service.content; - - -import org.craftercms.studio.api.v1.exception.ServiceLayerException; - -import java.util.Map; - -public interface ContentItemIdGenerator { - - /** - * Return unique ids required by content - * - * @return pair of id and value - */ - public Map getIds() throws ServiceLayerException; -} diff --git a/src/main/java/org/craftercms/studio/api/v1/service/content/ContentService.java b/src/main/java/org/craftercms/studio/api/v1/service/content/ContentService.java index 9b8524aee1..7662063c24 100644 --- a/src/main/java/org/craftercms/studio/api/v1/service/content/ContentService.java +++ b/src/main/java/org/craftercms/studio/api/v1/service/content/ContentService.java @@ -63,34 +63,6 @@ public interface ContentService { */ InputStream getContent(String site, String path) throws ContentNotFoundException; - /** - * get file size - * - * @param site site id where the operation will be executed - * @param path path to content - * @return Size in bytes - */ - long getContentSize(String site, String path); - - /** - * get content as string from repository - * - * @param site site identifier - * @param path path of the content - * @return document - */ - String getContentAsString(String site, String path); - - /** - * get content as string from repository - * - * @param site site identifier - * @param path path of the content - * @param encoding file encoding - * @return document - */ - String getContentAsString(String site, String path, String encoding); - /** * get document from wcm content * @@ -129,16 +101,6 @@ public interface ContentService { */ ContentItemTO getContentItem(String site, String path, int depth); - /** - * Retrieves the content type for a given path - * - * @param site the site id - * @param path the content path - * @return content type - * @throws DocumentException on failure to retrieve the content type from xml (when applicable) - */ - String getItemContentType(String site, String path) throws DocumentException, SiteNotFoundException; - /** * return the content for a given version * @@ -161,13 +123,6 @@ public interface ContentService { */ String getContentVersionAsString(String site, String path, String version) throws ContentNotFoundException; - /* THESE ARE NOT PUBLIC METHODS, DO NOT USE THE THEM */ - /* DEJAN TO CLEAN UP WHAT IS NOT TRULY PUBLIC */ - - ContentItemTO createDummyDmContentItemForDeletedNode(String site, String relativePath) throws SiteNotFoundException; - - String getContentTypeClass(String site, String uri) throws SiteNotFoundException; - List getItemOrders(String site, String path) throws ContentNotFoundException; double reorderItems(String site, String relativePath, String before, String after, String orderName) diff --git a/src/main/java/org/craftercms/studio/api/v1/service/content/ContentTypeService.java b/src/main/java/org/craftercms/studio/api/v1/service/content/ContentTypeService.java deleted file mode 100644 index 9c8d72343d..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/service/content/ContentTypeService.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.service.content; - -import org.craftercms.studio.api.v1.exception.ServiceLayerException; -import org.craftercms.studio.api.v1.exception.SiteNotFoundException; -import org.craftercms.studio.api.v1.to.ContentTypeConfigTO; -import org.craftercms.studio.api.v2.dal.security.NormalizedRole; - -import java.util.Collection; -import java.util.List; - -/** - * @author Dejan Brkic - */ -public interface ContentTypeService { - - /** - * get a content type by the given site and the content path - * - * @param site site identifier - * @param path path of the content - * @return content type - * @throws ServiceLayerException general service error - */ - ContentTypeConfigTO getContentTypeForContent(String site, String path) throws ServiceLayerException; - - /** - * check if the user is allowed to access the content type with the given user roles - * - * @param userRoles user roles - * @param item content type - * @return true if user has permissions to access the content type - */ - boolean isUserAllowed(Collection userRoles, ContentTypeConfigTO item); - - /** - * get a content type by the given site and type name - * - * @param site site identifier - * @param type content type name - * @return content type - */ - ContentTypeConfigTO getContentType(String site, String type) throws SiteNotFoundException; - - List getAllContentTypes(String site, boolean searchable) throws ServiceLayerException; - - List getAllowedContentTypesForPath(String site, String relativePath) throws ServiceLayerException; - - String getConfigPath(); -} - diff --git a/src/main/java/org/craftercms/studio/api/v1/service/security/SecurityService.java b/src/main/java/org/craftercms/studio/api/v1/service/security/SecurityService.java index 569f2f0dff..96f8fca471 100644 --- a/src/main/java/org/craftercms/studio/api/v1/service/security/SecurityService.java +++ b/src/main/java/org/craftercms/studio/api/v1/service/security/SecurityService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -21,7 +21,6 @@ import org.craftercms.studio.api.v1.exception.SiteNotFoundException; import org.craftercms.studio.api.v1.exception.security.UserNotFoundException; import org.craftercms.studio.api.v2.dal.security.NormalizedRole; -import org.springframework.security.core.Authentication; import java.util.Collection; import java.util.List; @@ -33,26 +32,6 @@ */ public interface SecurityService { - /** - * Returns the username of the current user OR NULL if no user is authenticated - * - * @return current user - * @deprecated use {@link org.craftercms.studio.impl.v2.utils.security.SecurityUtils#getCurrentUsername()} instead - */ - @Deprecated - String getCurrentUser(); - - /** - * Returns the {@link Authentication} for the current user or null if not user is authenticated. - * - * @return authentication - * @deprecated use {@link org.craftercms.studio.impl.v2.utils.security.SecurityUtils#getAuthentication()} instead - */ - @Deprecated - Authentication getAuthentication(); - - Set getUserRoles(String site); - @Valid Collection getUserRoles(String site, String user); Map getUserProfile(String user) throws ServiceLayerException, UserNotFoundException; diff --git a/src/main/java/org/craftercms/studio/api/v1/service/site/SiteService.java b/src/main/java/org/craftercms/studio/api/v1/service/site/SiteService.java deleted file mode 100644 index 4e95da7e4f..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/service/site/SiteService.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.api.v1.service.site; - -import org.craftercms.studio.api.v1.dal.SiteFeed; -import org.craftercms.studio.api.v1.exception.ServiceLayerException; -import org.craftercms.studio.api.v1.exception.security.UserNotFoundException; - -import java.util.List; - -/** - * Note: consider renaming - * A site in Crafter Studio is currently the name for a WEM project being managed. - * This service provides access to site configuration - * - * @author russdanner - */ -public interface SiteService { - - /** - * Check if site already exists - * - * @param site site ID - * @return true if site exists, false otherwise - */ - boolean exists(String site); - - /** - * Get total number of sites that user is allowed access to for given username - * - * @param username username - * @return number of sites - * @throws UserNotFoundException user not found - * @throws ServiceLayerException general service error - */ - int getSitesPerUserTotal(String username) throws UserNotFoundException, ServiceLayerException; - - /** - * Get sites that user is allowed access to for current user - * - * @param start start position for pagination - * @param number number of sites per page - * @return the list of sites - * @throws ServiceLayerException general service error - * @throws UserNotFoundException user not found - */ - List getSitesPerUser(int start, int number) throws UserNotFoundException, - ServiceLayerException; - - /** - * Get sites that user is allowed access to for given username - * - * @param username username - * @param start start position for pagination - * @param number number of sites per page - * @return the list of sites - * @throws UserNotFoundException user not found - * @throws ServiceLayerException general service error - */ - List getSitesPerUser(String username, int start, int number) throws UserNotFoundException, - ServiceLayerException; -} diff --git a/src/main/java/org/craftercms/studio/api/v1/to/ContentAssetInfoTO.java b/src/main/java/org/craftercms/studio/api/v1/to/ContentAssetInfoTO.java deleted file mode 100644 index 6d465f6389..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/to/ContentAssetInfoTO.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.to; - -import java.io.Serializable; - - -/** - * This class contains content asset information that exists in the repository - * - * @author hyanghee - */ -public class ContentAssetInfoTO implements Serializable { - - public static final String FILE_SIZE_KB = "KB"; - - /** - * - */ - protected static final long serialVersionUID = -8114663374929132828L; - - /** - * asset file name - **/ - protected String fileName; - /** - * asset file extension - **/ - protected String fileExtension; - /** - * asset file size in KB - **/ - protected double size; - /** - * the image width if the asset is an image - **/ - protected int width = -1; - /** - * the image height if the asset is an image - **/ - protected int height = -1; - - protected String sizeUnit = FILE_SIZE_KB; - - public String getSizeUnit() { - return sizeUnit; - } - - public void setSizeUnit(String sizeUnit) { - this.sizeUnit = sizeUnit; - } - - - /** - * @return the fileName - */ - public String getFileName() { - return fileName; - } - - /** - * @param fileName the fileName to set - */ - public void setFileName(String fileName) { - this.fileName = fileName; - } - - /** - * @return the fileExtension - */ - public String getFileExtension() { - return fileExtension; - } - - /** - * @param fileExtension the fileExtension to set - */ - public void setFileExtension(String fileExtension) { - this.fileExtension = fileExtension; - } - - /** - * @return the size - */ - public double getSize() { - return size; - } - - /** - * @param size the size to set - */ - public void setSize(double size) { - this.size = size; - } - - /** - * @return the width - */ - public int getWidth() { - return width; - } - - /** - * @param width the width to set - */ - public void setWidth(int width) { - this.width = width; - } - - /** - * @return the height - */ - public int getHeight() { - return height; - } - - /** - * @param height the height to set - */ - public void setHeight(int height) { - this.height = height; - } - -} diff --git a/src/main/java/org/craftercms/studio/api/v1/to/ContentItemTO.java b/src/main/java/org/craftercms/studio/api/v1/to/ContentItemTO.java index dce46b9f54..b600564f4e 100644 --- a/src/main/java/org/craftercms/studio/api/v1/to/ContentItemTO.java +++ b/src/main/java/org/craftercms/studio/api/v1/to/ContentItemTO.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -21,11 +21,6 @@ import java.util.ArrayList; import java.util.List; -import org.apache.commons.lang3.StringUtils; -import org.craftercms.studio.api.v1.util.DmContentItemComparator; - -import static org.craftercms.studio.api.v1.constant.StudioConstants.FILE_SEPARATOR; - /** * This class contains content item metadata * used by the UI @@ -108,7 +103,6 @@ public class ContentItemTO implements Serializable { public String categoryRoot; public ZonedDateTime lastEditDate; public String form; - public String formPagePath; public List renderingTemplates = new ArrayList<>(); public boolean folder; @@ -223,7 +217,6 @@ public ContentItemTO(ContentItemTO item, boolean cloneChildren) { this.lastEditDate = item.lastEditDate; } this.form = item.form; - this.formPagePath = item.formPagePath; this.renderingTemplates = item.renderingTemplates; this.folder = item.folder; @@ -611,14 +604,6 @@ public void setForm(String form) { this.form = form; } - public String getFormPagePath() { - return formPagePath; - } - - public void setFormPagePath(String formPagePath) { - this.formPagePath = formPagePath; - } - public boolean isFolder() { return folder; } @@ -766,256 +751,4 @@ public void setPackageId(String packageId) { this.packageId = packageId; } - public void addChild(ContentItemTO itemToAdd, boolean recursive, boolean renamed) { - - if (uri != null && uri.equals(itemToAdd.uri)) { - // do not add itself - return; - } - - if (recursive && (isNew || isDeleted || renamed) && !submittedForDeletion) { - itemToAdd.mandatoryParent = uri; - } - - if (children == null) { - children = new ArrayList<>(); - } - children.add(itemToAdd); - numOfChildren++; - } - - public void addChild(final ContentItemTO itemToAdd, DmContentItemComparator comparator, boolean recursive) { - addChild(itemToAdd, comparator, recursive, false); - } - - public void addChild(final ContentItemTO itemToAdd, DmContentItemComparator comparator, boolean recursive, - boolean renamed) { - if (uri != null && uri.equals(itemToAdd.uri)) { - // do not add itself - return; - } - - // if this content (parent) is a new file, set the mandatory parent of - // child items to be this content - // do not overwrite the mandatory parent in non-recursive case - // do not set mandatory parent if item is submittedForDeletion. - if (recursive && (isNew || isDeleted || renamed) && !submittedForDeletion - && !itemToAdd.isSubmittedForDeletion) { - itemToAdd.mandatoryParent = uri; - } - if (children != null) { - if (children.contains(itemToAdd)) { - return; - } - boolean added = false; - // position to add the item - int pos = 0; - // list to hold any child items found to be add to the itemToAdd - List childPositions = new ArrayList<>(children.size()); - for (int index = 0; index < children.size(); index++) { - ContentItemTO child = children.get(index); - String childUri = StringUtils.isEmpty(child.browserUri) ? child.uri : child.browserUri; - String itemToAddUri = StringUtils.isEmpty(itemToAdd.browserUri) ? itemToAdd.uri : itemToAdd.browserUri; - // for recursive case, check if the item being added should - // belong to one of the current level items - // or one of the current level items should belong to the item - // being added - if (recursive) { - int compareResult = comparator.compare(child, itemToAdd); - if (compareResult < 0) { - pos = index + 1 + 0; - } - // if the new item's URI starts with the URI of one of the - // item - // add the new item as a child of the item found - - if (StringUtils.isNotEmpty(itemToAddUri)) { - if (itemToAddUri.startsWith(childUri + FILE_SEPARATOR)) { - child.addChild(itemToAdd, comparator, recursive); - added = true; - break; - } else { - // if one of the item's URI starts with the URI of the - // new item - // add the item to the new item add replace it with the - // new item - if (StringUtils.isNotEmpty(childUri) && childUri.startsWith(itemToAddUri + FILE_SEPARATOR)) { - if (childPositions.size() == 0) { - // add the itemToAdd to the first child location - // and add the first child to itemToAdd - itemToAdd.addChild(child, comparator, recursive); - children.set(index, itemToAdd); - added = true; - } - childPositions.add(index); - } - } - } - // for non-recursive case, add the item being added to the - // current position - // if the current item is greater than the item - } else { - int compareResult = comparator.compare(itemToAdd, child); - if (compareResult < 0) { - children.add(index, itemToAdd); - added = true; - break; - } else { - pos = index + 1; - } - } - } - // if not added, add the new item to the right position - if (!added) { - children.add(pos, itemToAdd); - } - // if recursive case, check if there are more children to be added - // to itemToAdd - if (recursive && childPositions.size() > 1) { - for (int childIndex = 1; childIndex < childPositions.size(); childIndex++) { - int targetPosition = childPositions.get(childIndex); - // if there are more than 2 children added, - // make sure reduce the index by the number of children - // added - 1 - // since the list changes - if (childIndex > 1) { - targetPosition -= childIndex - 1; - } - itemToAdd.addChild(children.get(targetPosition), comparator, recursive); - children.remove(targetPosition); - } - } - } else { - children = new ArrayList<>(); - children.add(itemToAdd); - } - // increase the number of children by 1 - numOfChildren++; - } - - public void addChild(final ContentItemTO itemToAdd, DmContentItemComparator comparator, boolean recursive, - ChildFilter childFilter) { - if (uri != null && uri.equals(itemToAdd.getUri())) { - // do not add itself - return; - } - - // if this content (parent) is a new file, set the mandatory parent of - // child items to be this content - // do not overwrite the mandatory parent in non-recursive case - if (recursive && (isNew || isDeleted)) { - itemToAdd.setMandatoryParent(uri); - } - if (children != null) { - if (children.contains(itemToAdd)) { - return; - } - boolean added = false; - // position to add the item - int pos = 0; - // list to hold any child items found to be add to the itemToAdd - List childPositions = new ArrayList<>(children.size()); - for (int index = 0; index < children.size(); index++) { - ContentItemTO child = children.get(index); - String childUri = child.getBrowserUri(); - if (StringUtils.isEmpty(childUri)) { - childUri = child.getUri(); - } - String itemToAddUri = itemToAdd.getBrowserUri(); - if (StringUtils.isEmpty(itemToAddUri)) { - itemToAddUri = itemToAdd.getUri(); - } - // for recursive case, check if the item being added should - // belong to one of the current level items - // or one of the current level items should belong to the item - // being added - if (recursive) { - if (comparator.compare(child, itemToAdd) < 0) { - pos = index + 1 + 0; - } - // if the new item's URI starts with the URI of one of the - // item - // add the new item as a child of the item found - - if (itemToAddUri.startsWith(childUri + FILE_SEPARATOR)) { - child.addChild(itemToAdd, comparator, recursive); - added = true; - break; - } else { - // if one of the item's URI starts with the URI of the - // new item - // add the item to the new item add replace it with the - // new item - if (childUri.startsWith(itemToAddUri + FILE_SEPARATOR)) { - if (childPositions.size() == 0) { - // add the itemToAdd to the first child location - // and add the first child to itemToAdd - itemToAdd.addChild(child, comparator, recursive); - if (childFilter.accept(itemToAdd)) { - children.set(index, itemToAdd); - } - added = true; - } - childPositions.add(index); - } - } - // for non-recursive case, add the item being added to the - // current position - // if the current item is greater than the item - } else { - if (comparator.compare(itemToAdd, child) < 0) { - if (childFilter.accept(itemToAdd)) { - children.add(index, itemToAdd); - added = true; - } - break; - } else { - pos = index + 1; - } - } - } - // if not added, add the new item to the right position - if (!added) { - if (childFilter.accept(itemToAdd)) { - children.add(pos, itemToAdd); - } - } - // if recursive case, check if there are more children to be added - // to itemToAdd - if (recursive && childPositions.size() > 1) { - for (int childIndex = 1; childIndex < childPositions.size(); childIndex++) { - int targetPosition = childPositions.get(childIndex); - // if there are more than 2 children added, - // make sure reduce the index by the number of children - // added - 1 - // since the list changes - if (childIndex > 1) { - targetPosition -= childIndex - 1; - } - itemToAdd.addChild(children.get(targetPosition), comparator, recursive); - children.remove(targetPosition); - } - } - } else { - children = new ArrayList<>(); - if (childFilter.accept(itemToAdd)) { - children.add(itemToAdd); - } - } - // increase the number of children by 1 - numOfChildren++; - - } - - public interface ChildFilter { - - public boolean accept(ContentItemTO to); - } - - public class AcceptAllChildFilter implements ChildFilter { - - public boolean accept(ContentItemTO to) { - return true; - } - } } diff --git a/src/main/java/org/craftercms/studio/api/v1/to/ContentTypeConfigTO.java b/src/main/java/org/craftercms/studio/api/v1/to/ContentTypeConfigTO.java deleted file mode 100644 index c9b117f4aa..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/to/ContentTypeConfigTO.java +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (C) 2007-2024 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.to; - -import org.craftercms.studio.api.v2.dal.security.NormalizedRole; - -import java.io.Serializable; -import java.time.ZonedDateTime; -import java.util.List; -import java.util.Set; - - -/** - * DM Content type configuration - * - * @author hyanghee - */ -public class ContentTypeConfigTO implements TimeStamped, Serializable { - - /** - * - */ - protected static final long serialVersionUID = 1533739200033698413L; - - /** - * site content name - */ - protected String name = null; - - /** - * content type display name - */ - protected String label = null; - - /** - * content type form - */ - protected String form = null; - - /** - * content type form path - */ - protected String formPath = null; - - protected String type = null; - - /** - * create content in a folder wrapper? e.g. pageUrl: 101 means 101/index.xml instead of 101.xml - */ - protected boolean contentAsFolder = false; - - /** - * use rounded folder to arrange content? - */ - protected boolean useRoundedFolder = false; - - /** - * path to the model instance file (WCM) - */ - protected String modelInstancePath = null; - - /** - * list of roles allowed - **/ - protected Set allowedRoles = null; - - protected ZonedDateTime lastUpdated; - - /** - * list of delete association patterns that this content type is dependent on for deleting indexes in web project - **/ - protected List deleteDependencies = null; - - /** - * list of copy association patterns - **/ - protected List copyDepedencyPattern = null; - - /** - * is this content type previewable? - **/ - protected boolean isPreviewable = false; - - protected String imageThumbnail; - - protected boolean noThumbnail; - - /** - * the list of included paths - */ - protected List pathIncludes; - - /** - * the list of excluded paths - */ - protected List pathExcludes; - - /** - * the configuration noderef this content type is associated with - */ - protected String nodeRef; - - protected boolean quickCreate; - - protected String quickCreatePath; - - public String getImageThumbnail() { - return imageThumbnail; - } - - public void setImageThumbnail(String imageThumbnail) { - this.imageThumbnail = imageThumbnail; - } - - /** - * @return the label - */ - public String getLabel() { - return label; - } - - /** - * @param label the label to set - */ - public void setLabel(String label) { - this.label = label; - } - - /** - * @param form the form to set - */ - public void setForm(String form) { - this.form = form; - } - - /** - * @return the form - */ - public String getForm() { - return form; - } - - /** - * @param allowedRoles the allowedRoles to set - */ - public void setAllowedRoles(Set allowedRoles) { - this.allowedRoles = allowedRoles; - } - - /** - * @return the allowedRoles - */ - public Set getAllowedRoles() { - return allowedRoles; - } - - /** - * @param formPath the formPath to set - */ - public void setFormPath(String formPath) { - this.formPath = formPath; - } - - /** - * @return the formPath - */ - public String getFormPath() { - return formPath; - } - - /** - * @param name the name to set - */ - public void setName(String name) { - this.name = name; - } - - /** - * @return the name - */ - public String getName() { - return name; - } - - /** - * @param modelInstancePath the modelInstancePath to set - */ - public void setModelInstancePath(String modelInstancePath) { - this.modelInstancePath = modelInstancePath; - } - - /** - * @return the modelInstancePath - */ - public String getModelInstancePath() { - return modelInstancePath; - } - - /** - * @param deleteDependencies the deleteAssociations to set - */ - public void setDeleteDependencies(List deleteDependencies) { - this.deleteDependencies = deleteDependencies; - } - - /** - * @return the deleteAssociations - */ - public List getDeleteDependencyPattern() { - return deleteDependencies; - } - - /** - * @param lastUpdated the lastUpdated to set - */ - public void setLastUpdated(ZonedDateTime lastUpdated) { - this.lastUpdated = lastUpdated; - } - - /** - * @return the lastUpdated - */ - public ZonedDateTime getLastUpdated() { - return lastUpdated; - } - - /** - * @param contentAsFolder the contentAsFolder to set - */ - public void setContentAsFolder(boolean contentAsFolder) { - this.contentAsFolder = contentAsFolder; - } - - /** - * @return the contentAsFolder - */ - public boolean isContentAsFolder() { - return contentAsFolder; - } - - /** - * @return the isPreviewable - */ - public boolean isPreviewable() { - return isPreviewable; - } - - /** - * @param isPreviewable the isPreviewable to set - */ - public void setPreviewable(boolean isPreviewable) { - this.isPreviewable = isPreviewable; - } - - /** - * @param useRoundedFolder the useRoundedFolder to set - */ - public void setUseRoundedFolder(boolean useRoundedFolder) { - this.useRoundedFolder = useRoundedFolder; - } - - /** - * @return the useRoundedFolder - */ - public boolean isUseRoundedFolder() { - return useRoundedFolder; - } - - - public List getCopyDepedencyPattern() { - return copyDepedencyPattern; - } - - public void setCopyDepedencyPattern( - List copyDepedencyPattern) { - this.copyDepedencyPattern = copyDepedencyPattern; - } - - /** - * @return the pathIncludes - */ - public List getPathIncludes() { - return pathIncludes; - } - - /** - * @param pathIncludes the pathIncludes to set - */ - public void setPathIncludes(List pathIncludes) { - this.pathIncludes = pathIncludes; - } - - /** - * @return the pathExcludes - */ - public List getPathExcludes() { - return pathExcludes; - } - - /** - * @param pathExcludes the pathExcludes to set - */ - public void setPathExcludes(List pathExcludes) { - this.pathExcludes = pathExcludes; - } - - public boolean isNoThumbnail() { - return noThumbnail; - } - - public void setNoThumbnail(boolean noThumbnail) { - this.noThumbnail = noThumbnail; - } - - /** - * @return the nodeRef - */ - public String getNodeRef() { - return nodeRef; - } - - /** - * @param nodeRef the nodeRef to set - */ - public void setNodeRef(String nodeRef) { - this.nodeRef = nodeRef; - } - - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public boolean isQuickCreate() { - return quickCreate; - } - - public void setQuickCreate(boolean quickCreate) { - this.quickCreate = quickCreate; - } - - public String getQuickCreatePath() { - return quickCreatePath; - } - - public void setQuickCreatePath(String quickCreatePath) { - this.quickCreatePath = quickCreatePath; - } - - /* - * (non-Javadoc) - * @see java.lang.Object#toString() - */ - public String toString() { - return this.name; - } - -} diff --git a/src/main/java/org/craftercms/studio/api/v1/to/CopyDependencyConfigTO.java b/src/main/java/org/craftercms/studio/api/v1/to/CopyDependencyConfigTO.java deleted file mode 100644 index 7ab980c364..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/to/CopyDependencyConfigTO.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.to; - -import java.io.Serializable; - -/** - * holds the configuration for copy dependency - * - * @author Shankar Krishnan - */ -public class CopyDependencyConfigTO implements Serializable { - - private static final long serialVersionUID = 3853790978445959968L; - protected String pattern; - - protected String target; - - - public CopyDependencyConfigTO(String pattern, String target) { - super(); - this.pattern = pattern; - this.target = target; - } - - public String getPattern() { - return pattern; - } - - public void setPattern(String pattern) { - this.pattern = pattern; - } - - public String getTarget() { - return target; - } - - public void setTarget(String target) { - this.target = target; - } - -} diff --git a/src/main/java/org/craftercms/studio/api/v1/to/DeleteDependencyConfigTO.java b/src/main/java/org/craftercms/studio/api/v1/to/DeleteDependencyConfigTO.java deleted file mode 100644 index 78aafb62e7..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/to/DeleteDependencyConfigTO.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.to; - -import java.io.Serializable; - -/** - * holds the configuration for delete dependency - * - * @author Shankar Krishnan - */ -public class DeleteDependencyConfigTO implements Serializable { - - private static final long serialVersionUID = -8726953181196086267L; - protected String pattern; - - protected boolean removeEmptyFolder; - - - public DeleteDependencyConfigTO(String pattern, boolean removeEmptyFolder) { - super(); - this.pattern = pattern; - this.removeEmptyFolder = removeEmptyFolder; - } - - public String getPattern() { - return pattern; - } - - public void setPattern(String pattern) { - this.pattern = pattern; - } - - public boolean isRemoveEmptyFolder() { - return removeEmptyFolder; - } - - public void setRemoveEmptyFolder(boolean removeEmptyFolder) { - this.removeEmptyFolder = removeEmptyFolder; - } - - -} diff --git a/src/main/java/org/craftercms/studio/api/v1/util/DmContentItemComparator.java b/src/main/java/org/craftercms/studio/api/v1/util/DmContentItemComparator.java deleted file mode 100644 index 7a7d70d49b..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/util/DmContentItemComparator.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.util; - -import org.craftercms.studio.api.v1.to.ContentItemTO; -import org.craftercms.studio.impl.v1.util.ContentComparatorBase; - -public class DmContentItemComparator extends ContentComparatorBase { - - public static final String SORT_EVENT_DATE = "eventDate"; - public static final String SORT_INTERNAL_NAME = "internalName"; - public static final String SORT_BROWSER_URI = "browserUri"; - public static final String SORT_PATH = "path"; - public static final String SORT_USER_LAST_NAME = "userLastName"; - - /** - * if this is set to true, floating items will come last in the child list - **/ - protected boolean _listFloatingPagesLast; - /** - * if this is set to true, level descriptors will come first in the child list - **/ - protected boolean _listLevelDescriptorsFirst; - - protected String _secondLevelSortBy; - - protected boolean _isSecondLevelCompareRequired; - - protected boolean _secondLevelAscending; - - /** - * constructor that sets the sort key and the sort type - * - * @param sort sort strategy - * @param ascending if true order is ascending, otherwise descending - * @param listFloatingPagesLast if this is set to true, floating items will come last in the child list - * @param listLevelDescriptorsFirst if this is set to true, level descriptors will come first in the child list - */ - public DmContentItemComparator(final String sort, final boolean ascending, final boolean listFloatingPagesLast, - final boolean listLevelDescriptorsFirst) { - super(sort, ascending); - _listFloatingPagesLast = listFloatingPagesLast; - _listLevelDescriptorsFirst = listLevelDescriptorsFirst; - } - - public DmContentItemComparator(final String sort, final boolean ascending, final boolean listFloatingPagesLast, - final boolean listLevelDescriptorsFirst, final String secondLevelSortBy, - final boolean secLevelCompareReq, final boolean secLevAscending) { - this(sort, ascending, listFloatingPagesLast, listLevelDescriptorsFirst); - this._secondLevelSortBy = secondLevelSortBy; - this._isSecondLevelCompareRequired = secLevelCompareReq; - this._secondLevelAscending = secLevAscending; - } - - public boolean areEqual(ContentItemTO item1, ContentItemTO item2) { - if (item1 == null && item2 == null) { - return true; - } else if (item1 == null || item2 == null) { - return false; - } else { - return item1.equals(item2); - } - } - - public int hashCodeOf(ContentItemTO item) { - if (item != null) { - return item.hashCode(); - } else { - return 0; - } - } - - public int compare(final ContentItemTO item1, final ContentItemTO item2) { - // check for level descriptors - if (_listLevelDescriptorsFirst) { - if (item1.isLevelDescriptor && !item2.isLevelDescriptor) { - return (_ascending) ? -1 : 1; - } else if (!item1.isLevelDescriptor && item2.isLevelDescriptor) { - return (_ascending) ? 1 : -1; - } - } - // check for floating pages - if (_listFloatingPagesLast) { - if (item1.isFloating && !item2.isFloating) { - return (_ascending) ? 1 : -1; - } else if (!item1.isFloating && item2.isFloating) { - return (_ascending) ? -1 : 1; - } - } - // if no checking for floating page & level descriptors - // or both of them are the same type - // compare them by their metadata - if (SORT_EVENT_DATE.equals(_sort)) { - int rt = compareDates(item1.eventDate, item2.eventDate, _ascending); - if (rt == 0 && _isSecondLevelCompareRequired) { - return secondLevelCompare(item1, item2); - } - return rt; - - } else if (SORT_INTERNAL_NAME.equals(_sort)) { - String item1InternalName = (item1.internalName != null) ? item1.internalName.toLowerCase() : null; - String item2InternalName = (item2.internalName != null) ? item2.internalName.toLowerCase() : null; - int rt = compareStrings(item1InternalName, item2InternalName, _ascending); - if (rt == 0 && _isSecondLevelCompareRequired) { - return secondLevelCompare(item1, item2); - } - return rt; - } else if (SORT_BROWSER_URI.equals(_sort)) { - String item1Uri = (item1.browserUri != null) ? item1.browserUri.toLowerCase() : null; - String item2Uri = (item2.browserUri != null) ? item2.browserUri.toLowerCase() : null; - int rt = compareStrings(item1Uri, item2Uri, _ascending); - if (rt == 0 && _isSecondLevelCompareRequired) { - return secondLevelCompare(item1, item2); - } - return rt; - } else if (SORT_PATH.equals(_sort)) { - String item1Path = (item1.uri != null) ? item1.uri.toLowerCase() : null; - String item2Path = (item2.uri != null) ? item2.uri.toLowerCase() : null; - int rt = compareStrings(item1Path, item2Path, _ascending); - if (rt == 0 && _isSecondLevelCompareRequired) { - return secondLevelCompare(item1, item2); - } - return rt; - } else if (SORT_USER_LAST_NAME.equals(_sort)) { - String item1LastName = (item1.userLastName != null) ? item1.userLastName.toLowerCase() : null; - String item2LastName = (item2.userLastName != null) ? item2.userLastName.toLowerCase() : null; - int result = compareStrings(item1LastName, item2LastName, _ascending); - if (result == 0) { - String item1FirstName = (item1.userFirstName != null) ? item1.userFirstName.toLowerCase() : null; - String item2FirstName = (item2.userFirstName != null) ? item2.userFirstName.toLowerCase() : null; - return compareStrings(item1FirstName, item2FirstName, _ascending); - } else { - return result; - } - } - return 0; - } - - public int secondLevelCompare(final ContentItemTO item1, final ContentItemTO item2) { - // if no checking for floating page & level descriptors - // or both of them are the same type - // compare them by their metadata - if (SORT_EVENT_DATE.equals(_secondLevelSortBy)) { - return compareDates(item1.eventDate, item2.eventDate, _secondLevelAscending); - } else if (SORT_INTERNAL_NAME.equals(_secondLevelSortBy)) { - String item1InternalName = (item1.internalName != null) ? item1.internalName.toLowerCase() : null; - String item2InternalName = (item2.internalName != null) ? item2.internalName.toLowerCase() : null; - return compareStrings(item1InternalName, item2InternalName, _secondLevelAscending); - } else if (SORT_BROWSER_URI.equals(_secondLevelSortBy)) { - String item1Uri = (item1.browserUri != null) ? item1.browserUri.toLowerCase() : null; - String item2Uri = (item2.browserUri != null) ? item2.browserUri.toLowerCase() : null; - return compareStrings(item1Uri, item2Uri, _secondLevelAscending); - } else if (SORT_PATH.equals(_secondLevelSortBy)) { - String item1Path = (item1.uri != null) ? item1.uri.toLowerCase() : null; - String item2Path = (item2.uri != null) ? item2.uri.toLowerCase() : null; - return compareStrings(item1Path, item2Path, _secondLevelAscending); - } else if (SORT_USER_LAST_NAME.equals(_secondLevelSortBy)) { - String item1LastName = (item1.userLastName != null) ? item1.userLastName.toLowerCase() : null; - String item2LastName = (item2.userLastName != null) ? item2.userLastName.toLowerCase() : null; - int result = compareStrings(item1LastName, item2LastName, _secondLevelAscending); - if (result == 0) { - String item1FirstName = (item1.userFirstName != null) ? item1.userFirstName.toLowerCase() : null; - String item2FirstName = (item2.userFirstName != null) ? item2.userFirstName.toLowerCase() : null; - return compareStrings(item1FirstName, item2FirstName, _secondLevelAscending); - } else { - return result; - } - } - return 0; - } - - public void setListFloatingPagesLast(boolean listFloatingPagesLast) { - this._listFloatingPagesLast = listFloatingPagesLast; - } - - public boolean isListFloatingPagesLast() { - return _listFloatingPagesLast; - } - - public void setListLevelDescriptorsFirst(boolean listLevelDescriptorsFirst) { - this._listLevelDescriptorsFirst = listLevelDescriptorsFirst; - } - - public boolean isListLevelDescriptorsFirst() { - return _listLevelDescriptorsFirst; - } - - public String getSecondLevelSortBy() { - return _secondLevelSortBy; - } - - public void setSecondLevelSortBy(String secondLevelSort) { - this._secondLevelSortBy = secondLevelSort; - } - - public boolean isSecondLevelCompareRequired() { - return _isSecondLevelCompareRequired; - } - - public void setSecondLevelCompareRequired(boolean secondLevelCompareReq) { - _isSecondLevelCompareRequired = secondLevelCompareReq; - } - - public boolean isSecondLevelAscending() { - return _secondLevelAscending; - } - - public void setSecondLevelAscending(boolean secondLevelAscending) { - this._secondLevelAscending = secondLevelAscending; - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/util/filter/AbstractFilter.java b/src/main/java/org/craftercms/studio/api/v1/util/filter/AbstractFilter.java deleted file mode 100644 index 6fd98c9d7a..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/util/filter/AbstractFilter.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.util.filter; - -import org.craftercms.studio.api.v2.utils.StudioConfiguration; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -abstract public class AbstractFilter implements Filter { - - protected StudioConfiguration studioConfiguration; - - public abstract String getIncludePattern(); - - public void setStudioConfiguration(StudioConfiguration studioConfiguration) { - this.studioConfiguration = studioConfiguration; - } - - public boolean match(String contentType) { - if (contentType != null) { - String includePattern = getIncludePattern(); - Pattern pattern = Pattern.compile(includePattern); - Matcher matcher = pattern.matcher(contentType); - return matcher.matches(); - } - return false; - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/util/filter/AllFilter.java b/src/main/java/org/craftercms/studio/api/v1/util/filter/AllFilter.java deleted file mode 100644 index 0db708dc60..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/util/filter/AllFilter.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.util.filter; - -import org.craftercms.studio.api.v1.to.ContentItemTO; - -public class AllFilter extends AbstractFilter { - - /** - * filtering for all items. always returns true. - * - * @param item item - * @return true/false - */ - - public boolean filter(ContentItemTO item) { - return true; - } - - @Override - public String getIncludePattern() { - return ".*"; - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/util/filter/ComponentFilter.java b/src/main/java/org/craftercms/studio/api/v1/util/filter/ComponentFilter.java deleted file mode 100644 index 43081189cc..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/util/filter/ComponentFilter.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.util.filter; - -import org.craftercms.studio.api.v1.to.ContentItemTO; - -import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONTENT_TYPES_FILTER_COMPONENTS_INCLUDE_PATTERN; - -public class ComponentFilter extends AbstractFilter { - - @Override - public String getIncludePattern() { - return studioConfiguration.getProperty(CONTENT_TYPES_FILTER_COMPONENTS_INCLUDE_PATTERN); - } - - /** - * filtering for components. compared with contentType and - * contentType for pages is /cstudio-com/component/.... - * - * @param item item - * @return true/false - */ - - public boolean filter(ContentItemTO item) { - boolean isMatched = match(item.contentType); - boolean isComponent = (!item.document && isMatched); - item.component = isComponent; - return isComponent; - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/util/filter/DmFilterWrapper.java b/src/main/java/org/craftercms/studio/api/v1/util/filter/DmFilterWrapper.java deleted file mode 100644 index 2e1db5f008..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/util/filter/DmFilterWrapper.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.util.filter; - -import org.craftercms.studio.api.v1.exception.SiteNotFoundException; -import org.craftercms.studio.api.v1.to.ContentItemTO; - -/** - * @author Dejan Brkic - */ -public interface DmFilterWrapper { - public boolean accept(ContentItemTO item, String filterType); - - public boolean accept(String site, ContentItemTO item, String filterType) throws SiteNotFoundException; - - public boolean accept(String site, String relativePath, String filterType) throws SiteNotFoundException; - -} diff --git a/src/main/java/org/craftercms/studio/api/v1/util/filter/DmFilterWrapperImpl.java b/src/main/java/org/craftercms/studio/api/v1/util/filter/DmFilterWrapperImpl.java deleted file mode 100644 index 7b0dbdf539..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/util/filter/DmFilterWrapperImpl.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.util.filter; - -import org.craftercms.studio.api.v1.exception.SiteNotFoundException; -import org.craftercms.studio.api.v1.service.ServicesManager; -import org.craftercms.studio.api.v1.service.configuration.ServicesConfig; -import org.craftercms.studio.api.v1.to.ContentItemTO; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import static org.craftercms.studio.api.v1.constant.StudioConstants.*; -import static org.craftercms.studio.api.v2.utils.StudioUtils.matchesPatterns; - -public class DmFilterWrapperImpl implements DmFilterWrapper { - - protected Map _filterMap; - - public Map getFilterMap() { - return _filterMap; - } - - public void setFilterMap(Map filterMap) { - this._filterMap = filterMap; - } - - protected Filter _defaultFilter; - - public Filter getDefaultFilter() { - return _defaultFilter; - } - - public void setDefaultFilter(Filter defaultFilter) { - this._defaultFilter = defaultFilter; - } - - protected ServicesManager servicesManager; - - public void setServicesManager(ServicesManager servicesManager) { - this.servicesManager = servicesManager; - } - - protected ServicesConfig servicesConfig; - - public ServicesConfig getServicesConfig() { - return servicesConfig; - } - - public void setServicesConfig(ServicesConfig servicesConfig) { - this.servicesConfig = servicesConfig; - } - - @Override - public boolean accept(ContentItemTO item, String filterType) { - if (item != null) { - Filter filter = getFilter(filterType); - return filter.filter(item); - } - return false; - } - - @Override - public boolean accept(String site, ContentItemTO item, String filterType) throws SiteNotFoundException { - if (item != null) { - return accept(site, item.uri, filterType); - } - return false; - } - - protected Filter getFilter(String filterType) { - Filter filter = _defaultFilter; - if (filterType != null && _filterMap.get(filterType.toLowerCase()) != null) { - filter = _filterMap.get(filterType.toLowerCase()); - } - return filter; - } - - protected List getFilterPatterns(String site, String filterType) throws SiteNotFoundException { - if (CONTENT_TYPE_COMPONENT.equalsIgnoreCase(filterType)) { - List toRet = servicesConfig.getComponentPatterns(site); - List levelConfig = servicesConfig.getLevelDescriptorPatterns(site); - if (levelConfig != null) - toRet.addAll(levelConfig); - return toRet; - } else if (CONTENT_TYPE_ASSET.equalsIgnoreCase(filterType)) { - return servicesConfig.getAssetPatterns(site); - } else if (CONTENT_TYPE_RENDERING_TEMPLATE.equalsIgnoreCase(filterType)) { - return servicesConfig.getRenderingTemplatePatterns(site); - } else if (CONTENT_TYPE_DOCUMENT.equalsIgnoreCase(filterType)) { - return servicesConfig.getDocumentPatterns(site); - } else if (CONTENT_TYPE_ALL.equalsIgnoreCase(filterType)) { - return Arrays.asList(".*"); - } else if (CONTENT_TYPE_PAGE.equalsIgnoreCase(filterType)) { - return servicesConfig.getPagePatterns(site); - } else { - return null; - } - } - - @Override - public boolean accept(String site, String relativePath, String filterType) throws SiteNotFoundException { - if (relativePath != null) { - List patterns = getFilterPatterns(site, filterType); - if (patterns != null) { - return matchesPatterns(relativePath, patterns); - } - } - return false; - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/util/filter/DocumentFilter.java b/src/main/java/org/craftercms/studio/api/v1/util/filter/DocumentFilter.java deleted file mode 100644 index d218af84be..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/util/filter/DocumentFilter.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.util.filter; - -import org.craftercms.studio.api.v1.to.ContentItemTO; - -import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONTENT_TYPES_FILTER_DOCUMENTS_INCLUDE_PATTERN; - -public class DocumentFilter extends AbstractFilter { - - /** - * filtering for documents. compared with contentType and - * contentType for pages is /cstudio-com/document - * - * @param item item - * @return true/false - */ - - public boolean filter(ContentItemTO item) { - boolean isMatched = match(item.contentType); - boolean isDocument = (isMatched && !item.component); - item.document = isDocument; //it may have been set already, but still resetting. - return isDocument; - } - - @Override - public String getIncludePattern() { - return studioConfiguration.getProperty(CONTENT_TYPES_FILTER_DOCUMENTS_INCLUDE_PATTERN); - } -} diff --git a/src/main/java/org/craftercms/studio/api/v1/util/filter/Filter.java b/src/main/java/org/craftercms/studio/api/v1/util/filter/Filter.java deleted file mode 100644 index f288806cdb..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/util/filter/Filter.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.util.filter; - -import org.craftercms.studio.api.v1.to.ContentItemTO; - -public interface Filter { - public boolean filter(ContentItemTO item); -} diff --git a/src/main/java/org/craftercms/studio/api/v1/util/filter/PageFilter.java b/src/main/java/org/craftercms/studio/api/v1/util/filter/PageFilter.java deleted file mode 100644 index 8108a4654d..0000000000 --- a/src/main/java/org/craftercms/studio/api/v1/util/filter/PageFilter.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.api.v1.util.filter; - - -import org.craftercms.studio.api.v1.to.ContentItemTO; - -import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONTENT_TYPES_FILTER_PAGES_INCLUDE_PATTERN; - -public class PageFilter extends AbstractFilter { - - @Override - public String getIncludePattern() { - return studioConfiguration.getProperty(CONTENT_TYPES_FILTER_PAGES_INCLUDE_PATTERN); - } - - @Override - public boolean filter(ContentItemTO item) { - boolean isMatched = match(item.contentType); - return (!item.component && !item.document && isMatched); - } -} diff --git a/src/main/java/org/craftercms/studio/api/v2/annotation/RequireSiteReady.java b/src/main/java/org/craftercms/studio/api/v2/annotation/RequireSiteReady.java index 84016d9f66..e62512879e 100644 --- a/src/main/java/org/craftercms/studio/api/v2/annotation/RequireSiteReady.java +++ b/src/main/java/org/craftercms/studio/api/v2/annotation/RequireSiteReady.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,6 +16,8 @@ package org.craftercms.studio.api.v2.annotation; +import org.craftercms.studio.api.v2.dal.Site; + import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; @@ -23,7 +25,6 @@ import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; -import static org.craftercms.studio.api.v1.dal.SiteFeed.STATE_READY; /** * {@link RequireSiteState} specialization that requires the site state to be 'READY'. @@ -31,6 +32,6 @@ @Inherited @Retention(RUNTIME) @Target({METHOD, ElementType.TYPE}) -@RequireSiteState(STATE_READY) +@RequireSiteState(Site.State.READY) public @interface RequireSiteReady { } diff --git a/src/main/java/org/craftercms/studio/api/v2/dal/ItemDAO.java b/src/main/java/org/craftercms/studio/api/v2/dal/ItemDAO.java index bd744c5d5d..cf8b8cf704 100644 --- a/src/main/java/org/craftercms/studio/api/v2/dal/ItemDAO.java +++ b/src/main/java/org/craftercms/studio/api/v2/dal/ItemDAO.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -137,13 +137,6 @@ List getChildrenByPath(@Param(SITE_ID) Long siteId, */ ContentItem getContentItemByPathPreferContent(@Param(SITE_ID) long siteId, @Param(PATH) String path); - /** - * Update item - * - * @param item item to update - */ - void updateItem(Item item); - /** * Delete an item by path. * Notice that the parent folder will be deleted if path corresponds to a page. diff --git a/src/main/java/org/craftercms/studio/api/v2/dal/SiteDAO.java b/src/main/java/org/craftercms/studio/api/v2/dal/SiteDAO.java index 73568864e1..5a7232212a 100644 --- a/src/main/java/org/craftercms/studio/api/v2/dal/SiteDAO.java +++ b/src/main/java/org/craftercms/studio/api/v2/dal/SiteDAO.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -22,7 +22,6 @@ import java.util.List; import static org.craftercms.studio.api.v2.dal.QueryParameterNames.*; -import static org.craftercms.studio.api.v2.dal.QueryParameterNames.STATE; public interface SiteDAO { @@ -161,4 +160,22 @@ void duplicate(@Param(SOURCE_SITE_ID) String sourceSiteId, @Param(SITE_ID) Strin * @param stateReady the new state */ void setSiteState(@Param(SITE_ID) String siteId, @Param(STATE) String stateReady); + + /** + * Checks if there is a non-deleted site, different than the siteId, using the given name + * + * @param siteId the id of the site + * @param siteName the name of the site + * @return true if the name is being used by another site, false otherwise + */ + boolean isNameUsed(@Param(SITE_ID) String siteId, @Param(NAME) String siteName); + + /** + * Updates the name and description for the given site + * + * @param siteId the id of the site + * @param name the name of the site + * @param description the description of the site + */ + int updateSite(@Param(SITE_ID) String siteId, @Param(NAME) String name, @Param(DESC) String description); } diff --git a/src/main/java/org/craftercms/studio/api/v2/dal/publish/ItemTargetDAO.java b/src/main/java/org/craftercms/studio/api/v2/dal/publish/ItemTargetDAO.java index 1924ca2168..89cef82c14 100644 --- a/src/main/java/org/craftercms/studio/api/v2/dal/publish/ItemTargetDAO.java +++ b/src/main/java/org/craftercms/studio/api/v2/dal/publish/ItemTargetDAO.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2024 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -38,7 +38,6 @@ public interface ItemTargetDAO { String SITE_ID = "siteId"; String PACKAGE_ID = "packageId"; String COMMIT_ID = "commitId"; - String PATH = "path"; String TARGET = "target"; String LIVE_TARGET = "liveTarget"; String STAGING_TARGET = "stagingTarget"; diff --git a/src/main/java/org/craftercms/studio/api/v2/dal/repository/RemoteRepository.java b/src/main/java/org/craftercms/studio/api/v2/dal/repository/RemoteRepository.java index 101b0133bc..4b6f3e23da 100644 --- a/src/main/java/org/craftercms/studio/api/v2/dal/repository/RemoteRepository.java +++ b/src/main/java/org/craftercms/studio/api/v2/dal/repository/RemoteRepository.java @@ -17,7 +17,6 @@ package org.craftercms.studio.api.v2.dal.repository; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import org.craftercms.commons.git.utils.AuthenticationType; diff --git a/src/main/java/org/craftercms/studio/api/v2/repository/GitContentRepository.java b/src/main/java/org/craftercms/studio/api/v2/repository/GitContentRepository.java index a9aa25bf8f..c15b267cb8 100644 --- a/src/main/java/org/craftercms/studio/api/v2/repository/GitContentRepository.java +++ b/src/main/java/org/craftercms/studio/api/v2/repository/GitContentRepository.java @@ -395,19 +395,6 @@ String deleteContent(String siteId, Collection paths, */ String writeContent(String site, String path, InputStream content) throws ServiceLayerException, UserNotFoundException; - /** - * Create a folder in the repository - * - * @param site the site id - * @param path the path to create the folder - * @param name the name of the folder - * @return commit id after the operation - * @throws ServiceLayerException if the operation fails - * @throws UserNotFoundException if the current user is not found - */ - // TODO: remove this method once the create-folder API v1 is removed - String createFolder(String site, String path, String name) throws ServiceLayerException, UserNotFoundException; - /** * Create a folder in the repository * diff --git a/src/main/java/org/craftercms/studio/api/v2/service/content/ContentService.java b/src/main/java/org/craftercms/studio/api/v2/service/content/ContentService.java index 6952ae701e..8e3884526a 100644 --- a/src/main/java/org/craftercms/studio/api/v2/service/content/ContentService.java +++ b/src/main/java/org/craftercms/studio/api/v2/service/content/ContentService.java @@ -24,16 +24,17 @@ import org.craftercms.studio.api.v1.exception.SiteNotFoundException; import org.craftercms.studio.api.v1.exception.security.AuthenticationException; import org.craftercms.studio.api.v1.exception.security.UserNotFoundException; -import org.craftercms.studio.api.v2.dal.Site; import org.craftercms.studio.api.v2.dal.User; import org.craftercms.studio.api.v2.dal.item.ContentItem; import org.craftercms.studio.api.v2.dal.item.LightItem; -import org.craftercms.studio.api.v2.exception.content.ContentInPublishQueueException; import org.craftercms.studio.api.v2.exception.repository.RepositoryException; import org.craftercms.studio.model.history.ItemVersion; import org.craftercms.studio.model.history.RepositoryVersion; -import org.craftercms.studio.model.rest.content.*; +import org.craftercms.studio.model.rest.content.DeleteContentResult; import org.craftercms.studio.model.rest.content.GetChildrenBulkRequest.PathParams; +import org.craftercms.studio.model.rest.content.GetChildrenByPathsBulkResult; +import org.craftercms.studio.model.rest.content.PasteContentResult; +import org.craftercms.studio.model.rest.content.WriteContentResult; import org.dom4j.Document; import org.springframework.core.io.Resource; @@ -90,25 +91,6 @@ public interface ContentService { DeleteContentResult deleteContent(String siteId, Set paths, String publishTitle, String publishComment) throws ServiceLayerException, AuthenticationException, UserNotFoundException; - /** - * Get list of children for given path - * - * @param siteId site identifier - * @param path item path to children for - * @param locale filter children by locale - * @param keyword filter children by keyword - * @param types filter children by type - * @param excludes exclude items by path - * @param sortStrategy sort order - * @param order ascending or descending - * @param offset offset of the first child in the result - * @param limit number of children to return - * @return list of children - */ - GetChildrenResult getChildrenByPath(String siteId, String path, String locale, String keyword, List types, - List excludes, String sortStrategy, String order, int offset, int limit) - throws ServiceLayerException, UserNotFoundException; - /** * Get children for paths bulk. * This method will return children for a list of paths. Result items will also @@ -149,17 +131,6 @@ GetChildrenByPathsBulkResult getChildrenByPaths(String siteId, List path */ Document getItemDescriptor(String siteId, String path, boolean flatten) throws SiteNotFoundException, ContentNotFoundException; - /** - * Check if the content is part of any ready/processing publish package and fail if it is - * - * @param siteId the site id - * @param paths the paths to check - * @param includeChildren if true, check if any children of the paths are part of a publish package - * @throws ContentInPublishQueueException if the content is part of a publish package - */ - void assertNotInWorkflow(String siteId, List paths, boolean includeChildren) throws ServiceLayerException; - - /** * Get content size * @@ -392,18 +363,6 @@ PasteContentResult copy(String siteId, String sourcePath, String targetPath, Set */ WriteContentResult createFolder(String siteId, String path) throws ServiceLayerException, UserNotFoundException, AuthenticationException; - - /** - * Get content type class for given site and uri. - * It will default to {@link org.craftercms.studio.api.v1.constant.StudioConstants#CONTENT_TYPE_FILE} if - * the path does not match any content type pattern. - * @param site the site id - * @param uri the content uri - * @return the content type class - * @throws SiteNotFoundException if site is not found - */ - String getContentTypeClass(String site, String uri) throws SiteNotFoundException; - /** * Process the created files during a site creation. * diff --git a/src/main/java/org/craftercms/studio/api/v2/service/content/ContentTypeService.java b/src/main/java/org/craftercms/studio/api/v2/service/content/ContentTypeService.java index c3b3741625..c3a082a95e 100644 --- a/src/main/java/org/craftercms/studio/api/v2/service/content/ContentTypeService.java +++ b/src/main/java/org/craftercms/studio/api/v2/service/content/ContentTypeService.java @@ -73,7 +73,8 @@ void deleteContentType(String siteId, String contentType, boolean deleteDependen * * @param siteId the id of the site * @param contentTypeId the id of the content-type - * @return the form-controller.js file as a pair of path and resource, if exists, null otherwise + * @return the form-controller.js file as a pair of path and resource, if exists + * @throws org.craftercms.studio.api.v1.exception.ContentNotFoundException if the form-controller.js file does not exist for the given content type */ ImmutablePair getContentTypeFormController(String siteId, String contentTypeId) throws ServiceLayerException; @@ -109,6 +110,7 @@ void deleteContentType(String siteId, String contentType, boolean deleteDependen * * @param siteId site identifier * @return List of quick creatable content types + * @throws ServiceLayerException if there is any error getting the content types */ List getQuickCreatableContentTypes(String siteId) throws ServiceLayerException; diff --git a/src/main/java/org/craftercms/studio/api/v2/service/item/ItemService.java b/src/main/java/org/craftercms/studio/api/v2/service/item/ItemService.java index f91239f264..02ead8c327 100644 --- a/src/main/java/org/craftercms/studio/api/v2/service/item/ItemService.java +++ b/src/main/java/org/craftercms/studio/api/v2/service/item/ItemService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -31,13 +31,6 @@ public interface ItemService { - /** - * Insert record for item if it does not exist, otherwise update it - * - * @param item item to add or update - */ - void upsertEntry(Item item); - /** * Get item fir given site and path * @@ -57,13 +50,6 @@ public interface ItemService { */ Item getItem(String siteId, String path, boolean preferContent); - /** - * Update item - * - * @param item item to update - */ - void updateItem(Item item); - /** * Delete item with the given path. * @@ -93,16 +79,6 @@ default void setSystemProcessing(String siteId, String path, boolean isSystemPro */ void setSystemProcessingBulk(String siteId, Collection paths, boolean isSystemProcessing); - /** - * Update states to flip on list off states and flip off another list of states for item - * - * @param siteId site identifier - * @param path path of item - * @param onStateBitMap states bitmap to flip on - * @param offStateBitMap stats bitmap to flip off - */ - void updateStateBits(String siteId, String path, long onStateBitMap, long offStateBitMap); - Item.Builder instantiateItem(String siteName, String path); /** @@ -149,18 +125,6 @@ void persistItemAfterCreate(String siteId, String path, boolean unlock, Long par void persistItemAfterCreateFolder(String siteId, String folderPath, String folderName, Long parentId) throws ServiceLayerException, UserNotFoundException, AuthenticationException; - /** - * Persist item metadata after rename folder - * - * @param siteId site identifier - * @param path file path - * @param name file name - * @param contentType content type - * @throws ServiceLayerException if there is an error persisting the item - */ - void persistItemAfterRenameContent(String siteId, String path, String name, String contentType) - throws ServiceLayerException, AuthenticationException; - /** * Move item * diff --git a/src/main/java/org/craftercms/studio/api/v2/utils/StudioUtils.java b/src/main/java/org/craftercms/studio/api/v2/utils/StudioUtils.java index fdb6398af7..5c90d03444 100644 --- a/src/main/java/org/craftercms/studio/api/v2/utils/StudioUtils.java +++ b/src/main/java/org/craftercms/studio/api/v2/utils/StudioUtils.java @@ -52,6 +52,9 @@ public abstract class StudioUtils { private static final Logger logger = LoggerFactory.getLogger(StudioUtils.class); + protected static final Pattern COMPONENT_CONTENT_TYPE_ID_PATTERN = Pattern.compile("^/component/.*"); + protected static final Pattern PAGE_CONTENT_TYPE_ID_PATTERN = Pattern.compile("^/page/.*"); + public static String getMimeType(String filename) { MimetypesFileTypeMap mimeMap = new MimetypesFileTypeMap(); return mimeMap.getContentType(filename); @@ -255,12 +258,16 @@ public static String movePath(String sourceRoot, String targetRoot, String sourc * */ public static ContentType.Type getContentTypeTypeById(String contentTypeId) { - if (Pattern.matches("/component/.*?", contentTypeId)) { + if (isEmpty(contentTypeId)) { + return ContentType.Type.unknown; + } + + if (COMPONENT_CONTENT_TYPE_ID_PATTERN.matcher(contentTypeId).matches()) { return ContentType.Type.component; } - if (Pattern.matches("/page/.*?", contentTypeId)){ + if (PAGE_CONTENT_TYPE_ID_PATTERN.matcher(contentTypeId).matches()) { return ContentType.Type.page; - } + } return ContentType.Type.unknown; } } diff --git a/src/main/java/org/craftercms/studio/controller/rest/v2/aws/AwsS3Controller.java b/src/main/java/org/craftercms/studio/controller/rest/v2/aws/AwsS3Controller.java index 57af67998c..54c0806634 100644 --- a/src/main/java/org/craftercms/studio/controller/rest/v2/aws/AwsS3Controller.java +++ b/src/main/java/org/craftercms/studio/controller/rest/v2/aws/AwsS3Controller.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2024 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,6 +16,7 @@ package org.craftercms.studio.controller.rest.v2.aws; +import jakarta.validation.Constraint; import jakarta.validation.constraints.PositiveOrZero; import org.apache.commons.fileupload2.core.FileUploadException; import org.apache.commons.fileupload2.core.FileItemInput; @@ -46,6 +47,7 @@ import jakarta.servlet.http.HttpServletRequest; +import java.beans.ConstructorProperties; import java.io.IOException; import java.io.InputStream; @@ -66,8 +68,12 @@ @RequestMapping("/api/2/aws/s3") public class AwsS3Controller { - @Autowired - protected AwsS3Service s3Service; + protected final AwsS3Service s3Service; + + @ConstructorProperties("s3Service") + public AwsS3Controller(AwsS3Service s3Service) { + this.s3Service = s3Service; + } /** * List items in an S3 bucket. diff --git a/src/main/java/org/craftercms/studio/impl/v1/asset/processing/AssetProcessorPipelineImpl.java b/src/main/java/org/craftercms/studio/impl/v1/asset/processing/AssetProcessorPipelineImpl.java index 90a5994952..3bed8784b0 100644 --- a/src/main/java/org/craftercms/studio/impl/v1/asset/processing/AssetProcessorPipelineImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v1/asset/processing/AssetProcessorPipelineImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -40,7 +40,7 @@ */ public class AssetProcessorPipelineImpl implements AssetProcessorPipeline { - private AssetProcessorResolver processorFactory; + private final AssetProcessorResolver processorFactory; public AssetProcessorPipelineImpl(AssetProcessorResolver processorFactory) { this.processorFactory = processorFactory; diff --git a/src/main/java/org/craftercms/studio/impl/v1/asset/processing/AssetProcessorPipelineResolverImpl.java b/src/main/java/org/craftercms/studio/impl/v1/asset/processing/AssetProcessorPipelineResolverImpl.java index 8ec9d5a42a..f7825454e1 100644 --- a/src/main/java/org/craftercms/studio/impl/v1/asset/processing/AssetProcessorPipelineResolverImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v1/asset/processing/AssetProcessorPipelineResolverImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -27,7 +27,7 @@ */ public class AssetProcessorPipelineResolverImpl implements AssetProcessorPipelineResolver { - private AssetProcessorResolver processorResolver; + private final AssetProcessorResolver processorResolver; public AssetProcessorPipelineResolverImpl(AssetProcessorResolver processorResolver) { this.processorResolver = processorResolver; diff --git a/src/main/java/org/craftercms/studio/impl/v1/aws/elastictranscoder/ElasticTranscoderImpl.java b/src/main/java/org/craftercms/studio/impl/v1/aws/elastictranscoder/ElasticTranscoderImpl.java deleted file mode 100644 index 38e3914558..0000000000 --- a/src/main/java/org/craftercms/studio/impl/v1/aws/elastictranscoder/ElasticTranscoderImpl.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.impl.v1.aws.elastictranscoder; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang3.StringUtils; -import org.craftercms.commons.file.stores.S3Utils; -import org.craftercms.studio.api.v1.aws.elastictranscoder.ElasticTranscoder; -import org.craftercms.studio.api.v1.aws.elastictranscoder.TranscoderJob; -import org.craftercms.studio.api.v1.aws.elastictranscoder.TranscoderOutput; -import org.craftercms.studio.api.v1.aws.elastictranscoder.TranscoderProfile; -import org.craftercms.studio.api.v1.exception.AwsException; -import org.craftercms.studio.impl.v1.service.aws.AwsUtils; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.elastictranscoder.ElasticTranscoderClient; -import software.amazon.awssdk.services.elastictranscoder.model.*; -import software.amazon.awssdk.services.s3.S3Client; - -/** - * Default implementation of {@link ElasticTranscoder}. Just as indicated by the interface, the video file is first uploaded to the - * S3 input bucket of the AWS Elastic Transcoder pipeline, but before uploading, a unique bucket key is generated so that there's no - * issue when a file with the same filename is uploaded several times. In this way all video file versions (original or transcoded) are - * kept at all times and there's no downtime when a file is transcoded again. - * - * @author avasquez - */ -public class ElasticTranscoderImpl implements ElasticTranscoder { - - protected int partSize; - - public ElasticTranscoderImpl() { - partSize = AwsUtils.MIN_PART_SIZE; - } - - public void setPartSize(final int partSize) { - this.partSize = partSize; - } - - @Override - public TranscoderJob startJob(String filename, InputStream content, TranscoderProfile profile) throws AwsException { - try { - S3Client s3Client = getS3Client(profile); - ElasticTranscoderClient transcoderClient = getTranscoderClient(profile); - Pipeline pipeline = getPipeline(profile.getPipelineId(), transcoderClient); - String baseKey = FilenameUtils.removeExtension(filename) + "/" + UUID.randomUUID().toString(); - String inputKey = baseKey + "." + FilenameUtils.getExtension(filename); - - uploadInput(inputKey, filename, content, pipeline, s3Client); - - CreateJobResponse jobResult = createJob(inputKey, baseKey, profile, transcoderClient); - - return createResult(baseKey, jobResult, pipeline); - } catch (Exception e) { - throw new AwsException("Error while attempting to start an AWS Elastic Transcoder job for file " + filename, e); - } - } - - protected Pipeline getPipeline(String pipelineId, ElasticTranscoderClient client) { - ReadPipelineRequest readPipelineRequest = ReadPipelineRequest.builder() - .id(pipelineId) - .build(); - - ReadPipelineResponse response = client.readPipeline(readPipelineRequest); - - return response.pipeline(); - } - - protected void uploadInput(String inputKey, String filename, InputStream content, Pipeline pipeline, - S3Client s3Client) throws AwsException { - String inputBucket = pipeline.inputBucket(); - - AwsUtils.uploadStream(inputBucket, inputKey, s3Client, partSize, filename, content); - } - - protected CreateJobResponse createJob(String inputKey, String baseKey, TranscoderProfile profile, - ElasticTranscoderClient transcoderClient) { - CreateJobRequest jobRequest = getCreateJobRequest(inputKey, baseKey, profile); - CreateJobResponse jobResponse = transcoderClient.createJob(jobRequest); - - return jobResponse; - } - - protected TranscoderJob createResult(String baseKey, CreateJobResponse jobResponse, Pipeline pipeline) { - TranscoderJob job = new TranscoderJob(); - job.setId(jobResponse.job().id()); - job.setOutputBucket(pipeline.outputBucket()); - job.setBaseKey(baseKey); - - return job; - } - - protected S3Client getS3Client(TranscoderProfile profile) { - return S3Utils.createClient(profile); - } - - protected ElasticTranscoderClient getTranscoderClient(TranscoderProfile profile) { - return ElasticTranscoderClient.builder() - .credentialsProvider(profile.getCredentialsProvider()) - .region(Region.of(profile.getRegion())) - .build(); - } - - protected CreateJobRequest getCreateJobRequest(String inputKey, String baseKey, TranscoderProfile profile) { - JobInput jobInput = JobInput.builder() - .key(inputKey) - .build(); - - List jobOutputs = new ArrayList<>(profile.getOutputs().size()); - - for (TranscoderOutput output : profile.getOutputs()) { - jobOutputs.add(getCreateJobOutput(baseKey, output)); - } - - CreateJobRequest jobRequest = CreateJobRequest.builder() - .pipelineId(profile.getPipelineId()) - .input(jobInput) - .outputs(jobOutputs) - .build(); - - return jobRequest; - } - - protected CreateJobOutput getCreateJobOutput(String baseKey, TranscoderOutput output) { - CreateJobOutput.Builder builder = CreateJobOutput.builder() - .presetId(output.getPresetId()) - .key(baseKey + output.getOutputKeySuffix()); - - if (StringUtils.isNotEmpty(output.getThumbnailSuffixFormat())) { - builder.thumbnailPattern(baseKey + output.getThumbnailSuffixFormat()); - } - - return builder.build(); - } - -} - diff --git a/src/main/java/org/craftercms/studio/impl/v1/aws/mediaconvert/MediaConvertImpl.java b/src/main/java/org/craftercms/studio/impl/v1/aws/mediaconvert/MediaConvertImpl.java deleted file mode 100644 index aa7eadd4f0..0000000000 --- a/src/main/java/org/craftercms/studio/impl/v1/aws/mediaconvert/MediaConvertImpl.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.impl.v1.aws.mediaconvert; - -import java.io.InputStream; -import java.net.URI; - -import org.apache.commons.io.FilenameUtils; -import org.craftercms.commons.file.stores.S3Utils; -import org.craftercms.studio.api.v1.aws.mediaconvert.MediaConvert; -import org.craftercms.studio.api.v1.aws.mediaconvert.MediaConvertJob; -import org.craftercms.studio.api.v1.aws.mediaconvert.MediaConvertProfile; -import org.craftercms.studio.api.v1.exception.AwsException; -import org.craftercms.studio.impl.v1.service.aws.AwsUtils; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.mediaconvert.MediaConvertClient; -import software.amazon.awssdk.services.mediaconvert.model.*; -import software.amazon.awssdk.services.s3.S3Client; - -/** - * Default implementation of {@link MediaConvert}. - * - * @author joseross - */ -public class MediaConvertImpl implements MediaConvert { - - protected int partSize = AwsUtils.MIN_PART_SIZE; - - public void setPartSize(final int partSize) { - this.partSize = partSize; - } - - /** - * Creates an instance of {@link S3Client} to upload the files. - * - * @param profile AWS profile - * @return an S3 client - */ - protected S3Client getS3Client(MediaConvertProfile profile) { - return S3Utils.createClient(profile); - } - - /** - * Creates an instance of {@link MediaConvertClient} to start the transcoding jobs. - * - * @param profile AWS profile - * @return a MediaConvert client - */ - protected MediaConvertClient getMediaConvertClient(MediaConvertProfile profile) { - return MediaConvertClient.builder() - .credentialsProvider(profile.getCredentialsProvider()) - .region(Region.of(profile.getRegion())) - .endpointOverride(URI.create(profile.getEndpoint())) - .build(); - } - - /** - * Creates an instance of {@link MediaConvertJob} with the result of the transcoding job creation. - * - * @param createJobResponse result from the MediaConvert client - * @param destination output destination of the job - * @param key base filename for the output - * @return result of the transcoding job - */ - protected MediaConvertJob createMediaConverJob(CreateJobResponse createJobResponse, String destination, String key) { - MediaConvertJob job = new MediaConvertJob(); - job.setArn(createJobResponse.job().arn()); - job.setId(createJobResponse.job().id()); - job.setDestination(destination); - job.setBaseKey(key); - return job; - } - - /** - * {@inheritDoc} - */ - @Override - public MediaConvertJob startJob(final String filename, final InputStream content, final MediaConvertProfile profile) - throws AwsException { - S3Client s3Client = getS3Client(profile); - MediaConvertClient mediaConvertClient = getMediaConvertClient(profile); - - AwsUtils.uploadStream(profile.getInputPath(), filename, s3Client, partSize, filename, content); - - String key = FilenameUtils.getBaseName(filename); - - JobTemplate jobTemplate = mediaConvertClient.getJobTemplate( - GetJobTemplateRequest.builder() - .name(profile.getTemplate()) - .build()).jobTemplate(); - - JobSettings jobSettings = JobSettings.builder() - .inputs(Input.builder() - .fileInput(AwsUtils.getS3Url(profile.getInputPath(), filename)) - .build()) - .build(); - - CreateJobRequest createJobRequest = CreateJobRequest.builder() - .jobTemplate(profile.getTemplate()) - .settings(jobSettings) - .role(profile.getRole()) - .queue(profile.getQueue()) - .build(); - - CreateJobResponse createJobResult = mediaConvertClient.createJob(createJobRequest); - - return createMediaConverJob(createJobResult, getJobDestination(jobTemplate), key); - } - - /** - * Extracts the output destination from the transcoding job template settings. - * - * @param jobTemplate the job template used - * @return the output destination - */ - protected String getJobDestination(final JobTemplate jobTemplate) { - OutputGroup outputGroup = jobTemplate.settings().outputGroups().get(0); - OutputGroupType type = outputGroup.outputGroupSettings().type(); - switch (type) { - case FILE_GROUP_SETTINGS: - return outputGroup.outputGroupSettings().fileGroupSettings().destination(); - case HLS_GROUP_SETTINGS: - return outputGroup.outputGroupSettings().hlsGroupSettings().destination(); - case CMAF_GROUP_SETTINGS: - return outputGroup.outputGroupSettings().cmafGroupSettings().destination(); - case DASH_ISO_GROUP_SETTINGS: - return outputGroup.outputGroupSettings().dashIsoGroupSettings().destination(); - case MS_SMOOTH_GROUP_SETTINGS: - return outputGroup.outputGroupSettings().msSmoothGroupSettings().destination(); - default: - return null; - } - } - -} diff --git a/src/main/java/org/craftercms/studio/impl/v1/repository/git/GitContentRepositoryConstants.java b/src/main/java/org/craftercms/studio/impl/v1/repository/git/GitContentRepositoryConstants.java index a8fc4a358b..71c02c8a81 100644 --- a/src/main/java/org/craftercms/studio/impl/v1/repository/git/GitContentRepositoryConstants.java +++ b/src/main/java/org/craftercms/studio/impl/v1/repository/git/GitContentRepositoryConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -24,25 +24,18 @@ public final class GitContentRepositoryConstants { public static final String GIT_COMMIT_ALL_ITEMS = "."; public static final String EMPTY_FILE = ".keep"; public static final String IGNORE_FILE = ".gitignore"; - public static final String SOURCES_FOLDER = "sources"; public static final String[] IGNORE_FILES = new String[]{".keep", ".DS_Store"}; /** * Configuration */ public static final String CONFIG_SECTION_CORE = "core"; - public static final String CONFIG_SECTION_REMOTE = "remote"; public static final String CONFIG_PARAMETER_COMPRESSION = "compression"; public static final int CONFIG_PARAMETER_COMPRESSION_DEFAULT = 0; public static final String CONFIG_PARAMETER_BIG_FILE_THRESHOLD = "bigFileThreshold"; public static final String CONFIG_PARAMETER_BIG_FILE_THRESHOLD_DEFAULT = "20m"; public static final String CONFIG_PARAMETER_FILE_MODE = "fileMode"; public static final boolean CONFIG_PARAMETER_FILE_MODE_DEFAULT = false; - public static final String CONFIG_PARAMETER_URL = "url"; - public static final String CONFIG_PARAMETER_FETCH = "fetch"; - public static final String CONFIG_PARAMETER_FETCH_DEFAULT = "+refs/heads/*:refs/remotes/origin/*"; - - public static final String PREVIOUS_COMMIT_SUFFIX = "~1"; public static final String GIT_REPO_USER_USERNAME = "git_repo_user"; public static final String LOCK_FILE = "index.lock"; diff --git a/src/main/java/org/craftercms/studio/impl/v1/service/aws/ElasticTranscoderServiceImpl.java b/src/main/java/org/craftercms/studio/impl/v1/service/aws/ElasticTranscoderServiceImpl.java deleted file mode 100644 index c5d7f2d9a2..0000000000 --- a/src/main/java/org/craftercms/studio/impl/v1/service/aws/ElasticTranscoderServiceImpl.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.impl.v1.service.aws; - -import org.craftercms.commons.config.profiles.ConfigurationProfileNotFoundException; -import org.craftercms.commons.validation.annotations.param.ValidateStringParam; -import org.craftercms.studio.api.v1.aws.elastictranscoder.ElasticTranscoder; -import org.craftercms.studio.api.v1.aws.elastictranscoder.TranscoderJob; -import org.craftercms.studio.api.v1.aws.elastictranscoder.TranscoderProfile; -import org.craftercms.studio.api.v1.exception.AwsException; -import org.craftercms.studio.api.v1.service.aws.AbstractAwsService; -import org.craftercms.studio.api.v1.service.aws.ElasticTranscoderService; -import org.craftercms.studio.impl.v1.util.config.profiles.SiteAwareConfigProfileLoader; - -import jakarta.validation.Valid; - -import java.io.InputStream; - -/** - * Default implementation of {@link ElasticTranscoderService}. - * - * @author avasquez - */ -public class ElasticTranscoderServiceImpl extends AbstractAwsService implements ElasticTranscoderService { - - private ElasticTranscoder transcoder; - - public ElasticTranscoderServiceImpl(SiteAwareConfigProfileLoader profileLoader, ElasticTranscoder transcoder) { - super(profileLoader); - this.transcoder = transcoder; - } - - @Override - @Valid - public TranscoderJob transcodeFile(@ValidateStringParam String site, - @ValidateStringParam String profileId, - @ValidateStringParam String filename, - InputStream content) throws AwsException, ConfigurationProfileNotFoundException { - TranscoderProfile profile = getProfile(site, profileId); - TranscoderJob job = transcoder.startJob(filename, content, profile); - - return job; - } - -} diff --git a/src/main/java/org/craftercms/studio/impl/v1/service/aws/MediaConvertServiceImpl.java b/src/main/java/org/craftercms/studio/impl/v1/service/aws/MediaConvertServiceImpl.java deleted file mode 100644 index 7b202d1b10..0000000000 --- a/src/main/java/org/craftercms/studio/impl/v1/service/aws/MediaConvertServiceImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.impl.v1.service.aws; - -import java.io.InputStream; - -import org.craftercms.commons.config.profiles.ConfigurationProfileNotFoundException; -import org.craftercms.commons.validation.annotations.param.ValidateStringParam; -import org.craftercms.studio.api.v1.aws.mediaconvert.MediaConvert; -import org.craftercms.studio.api.v1.aws.mediaconvert.MediaConvertJob; -import org.craftercms.studio.api.v1.aws.mediaconvert.MediaConvertProfile; -import org.craftercms.studio.api.v1.exception.AwsException; -import org.craftercms.studio.api.v1.service.aws.AbstractAwsService; -import org.craftercms.studio.api.v1.service.aws.MediaConvertService; -import org.craftercms.studio.impl.v1.util.config.profiles.SiteAwareConfigProfileLoader; - -/** - * Default implementation of {@link MediaConvertService}. - * - * @author joseross - * @deprecated This service has been replaced with - * {@link org.craftercms.studio.impl.v2.service.aws.mediaconvert.AwsMediaConvertServiceImpl} - */ -@Deprecated -public class MediaConvertServiceImpl extends AbstractAwsService implements MediaConvertService { - - /** - * Instance of {@link MediaConvert}. - */ - protected MediaConvert mediaConvert; - - public MediaConvertServiceImpl(SiteAwareConfigProfileLoader profileLoader, final MediaConvert mediaConvert) { - super(profileLoader); - this.mediaConvert = mediaConvert; - } - - /** - * {@inheritDoc} - */ - @Override - public MediaConvertJob startJob(final @ValidateStringParam String site, - final @ValidateStringParam String profileId, - final @ValidateStringParam String filename, - final InputStream content) throws AwsException, ConfigurationProfileNotFoundException { - - MediaConvertProfile profile = getProfile(site, profileId); - - return mediaConvert.startJob(filename, content, profile); - } - -} diff --git a/src/main/java/org/craftercms/studio/impl/v1/service/aws/S3ServiceImpl.java b/src/main/java/org/craftercms/studio/impl/v1/service/aws/S3ServiceImpl.java deleted file mode 100644 index b820624a9e..0000000000 --- a/src/main/java/org/craftercms/studio/impl/v1/service/aws/S3ServiceImpl.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.impl.v1.service.aws; - -import org.craftercms.commons.config.profiles.ConfigurationProfileNotFoundException; -import org.craftercms.commons.config.profiles.aws.S3Profile; -import org.craftercms.commons.file.stores.S3Utils; -import org.craftercms.commons.validation.annotations.param.ValidateStringParam; -import org.craftercms.studio.api.v1.aws.s3.S3Output; -import org.craftercms.studio.api.v1.exception.AwsException; -import org.craftercms.studio.api.v1.service.aws.AbstractAwsService; -import org.craftercms.studio.api.v1.service.aws.S3Service; -import org.craftercms.studio.impl.v1.util.config.profiles.SiteAwareConfigProfileLoader; -import software.amazon.awssdk.services.s3.S3Client; - -import java.io.InputStream; - -/** - * Default implementation of {@link S3Service}. - * - * @author joseross - * @deprecated This service has been replaced with {@link org.craftercms.studio.impl.v2.service.aws.s3.AwsS3ServiceImpl} - */ -@Deprecated -public class S3ServiceImpl extends AbstractAwsService implements S3Service { - - protected int partSize; - - public S3ServiceImpl(SiteAwareConfigProfileLoader profileLoader) { - super(profileLoader); - partSize = AwsUtils.MIN_PART_SIZE; - } - - public void setPartSize(final int partSize) { - this.partSize = partSize; - } - - protected S3Client getS3Client(S3Profile profile) { - return S3Utils.createClient(profile); - } - - @Override - public S3Output uploadFile(@ValidateStringParam String site, - @ValidateStringParam String profileId, - @ValidateStringParam String filename, - InputStream content) throws AwsException, ConfigurationProfileNotFoundException { - S3Profile profile = getProfile(site, profileId); - S3Client s3Client = getS3Client(profile); - String inputBucket = profile.getBucketName(); - String inputKey = filename; - - AwsUtils.uploadStream(inputBucket, inputKey, s3Client, partSize, filename, content); - - S3Output output = new S3Output(); - output.setBucket(inputBucket); - output.setKey(inputKey); - return output; - } - -} diff --git a/src/main/java/org/craftercms/studio/impl/v1/service/configuration/ContentTypesConfigImpl.java b/src/main/java/org/craftercms/studio/impl/v1/service/configuration/ContentTypesConfigImpl.java deleted file mode 100644 index b17903aac1..0000000000 --- a/src/main/java/org/craftercms/studio/impl/v1/service/configuration/ContentTypesConfigImpl.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.impl.v1.service.configuration; - -import com.google.common.cache.Cache; -import jakarta.validation.Valid; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.craftercms.commons.validation.annotations.param.ValidateStringParam; -import org.craftercms.studio.api.v1.constant.StudioConstants; -import org.craftercms.studio.api.v1.exception.ServiceLayerException; -import org.craftercms.studio.api.v1.exception.SiteNotFoundException; -import org.craftercms.studio.api.v1.service.GeneralLockService; -import org.craftercms.studio.api.v1.service.configuration.ContentTypesConfig; -import org.craftercms.studio.api.v1.service.content.ContentService; -import org.craftercms.studio.api.v1.to.ContentTypeConfigTO; -import org.craftercms.studio.api.v1.to.CopyDependencyConfigTO; -import org.craftercms.studio.api.v1.to.DeleteDependencyConfigTO; -import org.craftercms.studio.api.v2.dal.security.NormalizedRole; -import org.craftercms.studio.api.v2.service.config.ConfigurationService; -import org.craftercms.studio.api.v2.utils.StudioConfiguration; -import org.craftercms.studio.api.v2.utils.StudioUtils; -import org.craftercms.studio.impl.v1.util.ContentFormatUtils; -import org.craftercms.studio.impl.v2.utils.DateUtils; -import org.dom4j.Document; -import org.dom4j.Element; -import org.dom4j.Node; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.regex.Pattern; - -import static org.craftercms.studio.api.v1.constant.StudioConstants.CONTENT_TYPE_UNKNOWN; -import static org.craftercms.studio.api.v1.constant.StudioConstants.FILE_SEPARATOR; -import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_FILE_NAME; -import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_PATH; -import static org.craftercms.studio.api.v2.utils.StudioUtils.getContentTypeTypeById; - -/** - * @author Dejan Brkic - */ -public class ContentTypesConfigImpl implements ContentTypesConfig { - - private static final Logger logger = LoggerFactory.getLogger(ContentTypesConfigImpl.class); - - private static final String QUICK_CREATE = "quickCreate"; - private static final String QUICK_CREATE_PATH = "quickCreatePath"; - - protected ContentService contentService; - protected GeneralLockService generalLockService; - protected StudioConfiguration studioConfiguration; - protected ConfigurationService configurationService; - - protected Cache cache; - - @Override - @Valid - public ContentTypeConfigTO getContentTypeConfig(@ValidateStringParam final String site, - @ValidateStringParam final String contentType) throws SiteNotFoundException { - if (StringUtils.isNotEmpty(contentType) && !StringUtils.equals(contentType, CONTENT_TYPE_UNKNOWN)) { - return loadConfiguration(site, contentType); - } - return null; - } - - @Override - @Valid - public ContentTypeConfigTO loadConfiguration(@ValidateStringParam String site, - @ValidateStringParam String contentType) throws SiteNotFoundException { - String siteConfigPath = getConfigPath().replaceAll(StudioConstants.PATTERN_SITE, site) - .replaceAll(StudioConstants.PATTERN_CONTENT_TYPE, contentType); - String configFileFullPath = siteConfigPath + FILE_SEPARATOR + getConfigFileName(); - - // TODO: SJ: Add general lock service lock around this key to avoid having more than one thread do this work - var cacheKey = configurationService.getCacheKey(site, null, configFileFullPath, - null, "object"); - ContentTypeConfigTO contentTypeConfig = cache.getIfPresent(cacheKey); - if (contentTypeConfig == null) { - try { - logger.debug("Cache miss for key '{}'", cacheKey); - - if (contentService.contentExists(site, configFileFullPath)) { - Document document = configurationService.getConfigurationAsDocument(site, null, - configFileFullPath, null); - Element root = document.getRootElement(); - String name = root.valueOf("@name"); - contentTypeConfig = new ContentTypeConfigTO(); - contentTypeConfig.setName(name); - contentTypeConfig.setLabel(root.valueOf("label")); - String imageThumbnail = root.valueOf("image-thumbnail"); - if (imageThumbnail != null) - contentTypeConfig.setImageThumbnail(imageThumbnail); - contentTypeConfig.setForm(root.valueOf("form")); - boolean previewable = ContentFormatUtils.getBooleanValue(root.valueOf("previewable")); - contentTypeConfig.setFormPath(root.valueOf("form-path")); - contentTypeConfig.setPreviewable(previewable); - contentTypeConfig.setModelInstancePath(root.valueOf("model-instance-path")); - boolean contentAsFolder = ContentFormatUtils.getBooleanValue(root.valueOf("content-as-folder")); - contentTypeConfig.setContentAsFolder(contentAsFolder); - boolean useRoundedFolder = ContentFormatUtils.getBooleanValue(root.valueOf("use-rounded-folder")); - contentTypeConfig.setUseRoundedFolder(useRoundedFolder); - List pathIncludes = getPaths(root, "paths/includes/pattern"); - if (pathIncludes.size() == 0) { - // if no configuration, include every path - pathIncludes.add(".*"); - } - contentTypeConfig.setPathIncludes(pathIncludes); - List pathExcludes = getPaths(root, "paths/excludes/pattern"); - contentTypeConfig.setPathExcludes(pathExcludes); - loadRoles(contentTypeConfig, root.selectNodes("allowed-roles/role")); - loadDeleteDependencies(contentTypeConfig, root.selectNodes("delete-dependencies/delete-dependency")); - loadCopyDependencyPatterns(contentTypeConfig, root.selectNodes("copy-dependencies/copy-dependency")); - contentTypeConfig.setLastUpdated(DateUtils.getCurrentTime()); - contentTypeConfig.setType(getContentTypeTypeById(name).name()); - boolean quickCreate = ContentFormatUtils.getBooleanValue(root.valueOf(QUICK_CREATE)); - contentTypeConfig.setQuickCreate(quickCreate); - contentTypeConfig.setQuickCreatePath(root.valueOf(QUICK_CREATE_PATH)); - - cache.put(cacheKey, contentTypeConfig); - } - } catch (ServiceLayerException e) { - logger.error("No content type configuration document found in site '{}' at '{}'", - site, configFileFullPath, e); - } - } - return contentTypeConfig; - } - - /** - * load delete dependencies mapping - * - * @param contentTypeConfig - * @param nodes - */ - protected void loadDeleteDependencies(ContentTypeConfigTO contentTypeConfig, List nodes) { - List deleteConfigs = new ArrayList<>(); - if (nodes != null) { - for (Node node : nodes) { - Node patternNode = node.selectSingleNode("pattern"); - Node removeFolderNode = node.selectSingleNode("remove-empty-folder"); - if (patternNode != null) { - String pattern = patternNode.getText(); - String removeEmptyFolder = removeFolderNode.getText(); - boolean isRemoveEmptyFolder = false; - if (removeEmptyFolder != null) { - isRemoveEmptyFolder = Boolean.parseBoolean(removeEmptyFolder); - } - if (StringUtils.isNotEmpty(pattern)) { - DeleteDependencyConfigTO deleteConfigTO = - new DeleteDependencyConfigTO(pattern, isRemoveEmptyFolder); - deleteConfigs.add(deleteConfigTO); - } - } - } - contentTypeConfig.setDeleteDependencies(deleteConfigs); - } - } - - /** - * get paths - * - * @param root - * @param path - * @return get paths - */ - private List getPaths(Element root, String path) { - List paths = null; - List nodes = root.selectNodes(path); - if (nodes != null && nodes.size() > 0) { - paths = new ArrayList<>(nodes.size()); - for (Node node : nodes) { - String role = node.getText(); - if (!StringUtils.isEmpty(role)) { - paths.add(role); - } - } - } else { - paths = new ArrayList<>(); - } - return paths; - } - - /** - * load a list of allowed roles - * - * @param config - * @param nodes - */ - protected void loadRoles(ContentTypeConfigTO config, List nodes) { - Set roles; - if (!CollectionUtils.isEmpty(nodes)) { - roles = new HashSet<>(nodes.size()); - for (Node node : nodes) { - String role = node.getText(); - if (!StringUtils.isEmpty(role)) { - roles.add(new NormalizedRole(role)); - } - } - } else { - roles = new HashSet<>(); - } - config.setAllowedRoles(roles); - } - - /** - * @param config - * @param copyDependencyNodes - */ - protected void loadCopyDependencyPatterns(ContentTypeConfigTO config, List copyDependencyNodes) { - List copyConfig = new ArrayList<>(); - if (copyDependencyNodes != null) { - for (Node copyDependency : copyDependencyNodes) { - Node patternNode = copyDependency.selectSingleNode("pattern"); - Node targetNode = copyDependency.selectSingleNode("target"); - if (patternNode != null && targetNode != null) { - String pattern = patternNode.getText(); - String target = targetNode.getText(); - if (StringUtils.isNotEmpty(pattern) && StringUtils.isNotEmpty(target)) { - CopyDependencyConfigTO copyDependencyConfigTO = new CopyDependencyConfigTO(pattern, target); - copyConfig.add(copyDependencyConfigTO); - } - } - } - } - config.setCopyDepedencyPattern(copyConfig); - - } - - - @Override - @Valid - public ContentTypeConfigTO reloadConfiguration(@ValidateStringParam String site, - @ValidateStringParam String contentType) throws SiteNotFoundException { - return loadConfiguration(site, contentType); - } - - public String getConfigPath() { - return studioConfiguration.getProperty(CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_PATH); - } - - public String getConfigFileName() { - return studioConfiguration.getProperty(CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_FILE_NAME); - } - - public ContentService getContentService() { - return contentService; - } - - public void setContentService(ContentService contentService) { - this.contentService = contentService; - } - - public GeneralLockService getGeneralLockService() { - return generalLockService; - } - - public void setGeneralLockService(GeneralLockService generalLockService) { - this.generalLockService = generalLockService; - } - - public StudioConfiguration getStudioConfiguration() { - return studioConfiguration; - } - - public void setStudioConfiguration(StudioConfiguration studioConfiguration) { - this.studioConfiguration = studioConfiguration; - } - - public void setConfigurationService(ConfigurationService configurationService) { - this.configurationService = configurationService; - } - - public void setCache(Cache cache) { - this.cache = cache; - } - -} diff --git a/src/main/java/org/craftercms/studio/impl/v1/service/configuration/ServicesConfigImpl.java b/src/main/java/org/craftercms/studio/impl/v1/service/configuration/ServicesConfigImpl.java index 6cd38acc2d..66c31d52ed 100644 --- a/src/main/java/org/craftercms/studio/impl/v1/service/configuration/ServicesConfigImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v1/service/configuration/ServicesConfigImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -25,12 +25,10 @@ import org.craftercms.core.util.XmlUtils; import org.craftercms.studio.api.v1.exception.ServiceLayerException; import org.craftercms.studio.api.v1.exception.SiteNotFoundException; -import org.craftercms.studio.api.v1.service.configuration.ContentTypesConfig; import org.craftercms.studio.api.v1.service.configuration.ServicesConfig; import org.craftercms.studio.api.v1.to.*; import org.craftercms.studio.api.v2.service.config.ConfigurationService; import org.craftercms.studio.api.v2.utils.StudioConfiguration; -import org.craftercms.studio.impl.v1.util.ContentFormatUtils; import org.craftercms.studio.impl.v2.utils.DateUtils; import org.dom4j.Document; import org.dom4j.Element; @@ -43,7 +41,6 @@ import java.util.function.Function; import java.util.stream.Collectors; -import static java.util.Collections.emptyList; import static org.craftercms.studio.api.v1.constant.StudioConstants.*; import static org.craftercms.studio.api.v2.utils.StudioConfiguration.*; @@ -82,21 +79,10 @@ public class ServicesConfigImpl implements ServicesConfig { protected static final String ATTR_READ_DIRECT_CHILDREN = "@read-direct-children"; protected static final String ATTR_ATTACH_ROOT_PREFIX = "@attach-root-prefix"; - /** - * content types configuration - */ - protected ContentTypesConfig contentTypesConfig; protected StudioConfiguration studioConfiguration; protected ConfigurationService configurationService; protected Cache configurationCache; - @Override - @Valid - public ContentTypeConfigTO getContentTypeConfig(@ValidateStringParam String site, - @ValidateStringParam String name) throws SiteNotFoundException { - return contentTypesConfig.getContentTypeConfig(site, name); - } - @Override @Valid public List getAssetPatterns(@ValidateStringParam String site) throws SiteNotFoundException { @@ -107,20 +93,6 @@ public List getAssetPatterns(@ValidateStringParam String site) throws Si return null; } - @Override - @Valid - public List getCopyDependencyPatterns(@ValidateStringParam String site, - @ValidateStringParam String contentType) throws SiteNotFoundException { - if (contentType == null) { - return emptyList(); - } - ContentTypeConfigTO contentTypeConfig = contentTypesConfig.getContentTypeConfig(site, contentType); - if (contentTypeConfig != null) { - return contentTypeConfig.getCopyDepedencyPattern(); - } - return emptyList(); - } - @Override @Valid public List getComponentPatterns(@ValidateStringParam String site) throws SiteNotFoundException { @@ -490,9 +462,9 @@ protected void loadFolderConfiguration(SiteConfigTO site, RepositoryConfigTO rep folderConfig.setName(folderNode.valueOf(ATTR_NAME)); folderConfig.setPath(folderNode.valueOf(ATTR_PATH)); folderConfig.setReadDirectChildren( - ContentFormatUtils.getBooleanValue(folderNode.valueOf(ATTR_READ_DIRECT_CHILDREN))); + Boolean.parseBoolean(folderNode.valueOf(ATTR_READ_DIRECT_CHILDREN))); folderConfig.setAttachRootPrefix( - ContentFormatUtils.getBooleanValue(folderNode.valueOf(ATTR_ATTACH_ROOT_PREFIX))); + Boolean.parseBoolean(folderNode.valueOf(ATTR_ATTACH_ROOT_PREFIX))); folders.add(folderConfig); } repo.setFolders(folders); @@ -590,11 +562,6 @@ public ContentMonitorConfigTO getMonitorConfig(String siteId) throws SiteNotFoun return config.getContentMonitorConfig(); } - @SuppressWarnings("unused") - public void setContentTypesConfig(ContentTypesConfig contentTypesConfig) { - this.contentTypesConfig = contentTypesConfig; - } - public void setStudioConfiguration(StudioConfiguration studioConfiguration) { this.studioConfiguration = studioConfiguration; } diff --git a/src/main/java/org/craftercms/studio/impl/v1/service/content/ContentItemIdGeneratorImpl.java b/src/main/java/org/craftercms/studio/impl/v1/service/content/ContentItemIdGeneratorImpl.java deleted file mode 100644 index 987208da7f..0000000000 --- a/src/main/java/org/craftercms/studio/impl/v1/service/content/ContentItemIdGeneratorImpl.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.impl.v1.service.content; - - -import org.craftercms.studio.api.v1.constant.DmConstants; -import org.craftercms.studio.api.v1.exception.ServiceLayerException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.craftercms.studio.api.v1.service.AbstractRegistrableService; -import org.craftercms.studio.api.v1.service.content.ContentItemIdGenerator; - -import java.util.HashMap; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.UUID; - -public class ContentItemIdGeneratorImpl extends AbstractRegistrableService implements ContentItemIdGenerator { - - protected static final Logger logger = LoggerFactory.getLogger(ContentItemIdGeneratorImpl.class); - - @Override - public void register() { - this._servicesManager.registerService(ContentItemIdGenerator.class, this); - } - - @Override - public Map getIds() throws ServiceLayerException { - Map params = new HashMap<>(); - String pageId = UUID.randomUUID().toString(); - String groupId; - StringTokenizer tokenizer = new StringTokenizer(pageId, "-"); - if (tokenizer.countTokens() > 0) { - groupId = tokenizer.nextToken(); - } else { - groupId = pageId.substring(0, 4); - } - params.put(DmConstants.KEY_PAGE_ID, pageId); - params.put(DmConstants.KEY_PAGE_GROUP_ID, groupId); - return params; - } - -} diff --git a/src/main/java/org/craftercms/studio/impl/v1/service/content/ContentServiceImpl.java b/src/main/java/org/craftercms/studio/impl/v1/service/content/ContentServiceImpl.java index 3a282afe70..7013806719 100644 --- a/src/main/java/org/craftercms/studio/impl/v1/service/content/ContentServiceImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v1/service/content/ContentServiceImpl.java @@ -31,20 +31,17 @@ import org.craftercms.studio.api.v1.exception.security.UserNotFoundException; import org.craftercms.studio.api.v1.service.configuration.ServicesConfig; import org.craftercms.studio.api.v1.service.content.ContentService; -import org.craftercms.studio.api.v1.service.content.ContentTypeService; import org.craftercms.studio.api.v1.service.content.DmPageNavigationOrderService; import org.craftercms.studio.api.v1.to.ContentItemTO; -import org.craftercms.studio.api.v1.to.ContentTypeConfigTO; import org.craftercms.studio.api.v1.to.DmOrderTO; import org.craftercms.studio.api.v1.to.RenderingTemplateTO; import org.craftercms.studio.api.v2.annotation.LogExecutionTime; -import org.craftercms.studio.api.v2.annotation.RequireSiteExists; -import org.craftercms.studio.api.v2.annotation.SiteId; import org.craftercms.studio.api.v2.dal.Item; import org.craftercms.studio.api.v2.dal.User; import org.craftercms.studio.api.v2.dal.publish.PublishPackage; import org.craftercms.studio.api.v2.repository.GitContentRepository; import org.craftercms.studio.api.v2.repository.RepositoryItem; +import org.craftercms.studio.api.v2.service.content.ContentTypeService; import org.craftercms.studio.api.v2.service.item.ItemService; import org.craftercms.studio.api.v2.service.publish.PublishService; import org.craftercms.studio.api.v2.service.security.UserService; @@ -52,7 +49,7 @@ import org.craftercms.studio.api.v2.utils.StudioUtils; import org.craftercms.studio.impl.v1.util.ContentItemOrderComparator; import org.craftercms.studio.impl.v1.util.ContentUtils; -import org.craftercms.studio.impl.v2.utils.TimeUtils; +import org.craftercms.studio.model.contentType.ContentType; import org.craftercms.studio.model.rest.Person; import org.dom4j.Document; import org.dom4j.DocumentException; @@ -74,17 +71,15 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import static java.lang.String.format; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Objects.isNull; import static org.apache.commons.lang3.StringUtils.isEmpty; -import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static org.craftercms.studio.api.v1.constant.DmConstants.*; -import static org.craftercms.studio.api.v1.constant.StudioConstants.INDEX_FILE; +import static org.craftercms.studio.api.v1.constant.DmConstants.SLASH_INDEX_FILE; +import static org.craftercms.studio.api.v1.constant.DmConstants.SLASH_SITE_WEBSITE; import static org.craftercms.studio.api.v1.constant.StudioConstants.*; -import static org.craftercms.studio.api.v1.constant.StudioXmlConstants.DOCUMENT_ELM_CONTENT_TYPE; import static org.craftercms.studio.api.v2.dal.ItemState.*; import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_GLOBAL_SYSTEM_SITE; +import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_BASE_PATH; import static org.craftercms.studio.api.v2.utils.StudioUtils.matchesPatterns; /** @@ -103,11 +98,11 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa protected ServicesConfig servicesConfig; protected DmPageNavigationOrderService dmPageNavigationOrderService; protected StudioConfiguration studioConfiguration; - protected ContentTypeService contentTypeService; protected ItemService itemService; protected UserService userService; protected ApplicationContext applicationContext; protected PublishService publishService; + protected ContentTypeService contentTypeService; @Deprecated @Override @@ -138,46 +133,6 @@ public InputStream getContent(String site, } } - @Override - @Valid - public long getContentSize(@ValidateStringParam String site, - @ValidateStringParam String path) { - return contentRepository.getContentSize(site, path); - } - - @Override - @Valid - public String getContentAsString(String site, - @ValidateSecurePathParam String path) { - return getContentAsString(site, path, null); - } - - @Override - @Valid - public String getContentAsString(@ValidSiteId String site, - @ValidateSecurePathParam String path, - String encoding) { - return getContentAsStringInternal(site, path, encoding, false); - } - - private String getContentAsStringInternal(String site, String path, String encoding, boolean shallow) { - return TimeUtils.logExecutionTime(() -> { - String content = null; - try (InputStream is = contentRepository.getContent(site, path, shallow)) { - if (is != null) { - if (isEmpty(encoding)) { - content = IOUtils.toString(is, UTF_8); - } else { - content = IOUtils.toString(is, encoding); - } - } - } catch (Exception e) { - logger.debug("Failed to get content as string from site '{}' path '{}'", site, path, e); - } - return content; - }, logger, format("Method 'ContentServiceImpl.getContentAsStringInternal(..)' with parameters %s", Arrays.asList(site, path, encoding, shallow))); - } - @Override @Valid public Document getContentAsDocument(@ValidateStringParam String site, @@ -516,35 +471,7 @@ public ContentItemTO getContentItem(@ValidSiteId String site, return item; } - @Override - @RequireSiteExists - public String getItemContentType(@SiteId String site, String path) throws DocumentException, SiteNotFoundException { - Item item = itemService.getItem(site, path); - if (item == null) { - return getContentTypeClass(site, path); - } - Pattern taxonomyPattern = Pattern.compile(CONTENT_TYPE_TAXONOMY_REGEX); - Matcher matcher = taxonomyPattern.matcher(path); - if (matcher.matches()) { - return CONTENT_TYPE_TAXONOMY; - } - if (isNotEmpty(item.getContentTypeId())) { - return item.getContentTypeId(); - } - if (CONTENT_TYPE_FOLDER.equals(item.getSystemType())) { - return CONTENT_TYPE_FOLDER; - } - if (path.endsWith(XML_PATTERN) && !path.startsWith(CONFIG_PATH_ROOT)) { - Document contentDoc = this.getContentAsDocument(site, path); - if (contentDoc != null) { - Element rootElement = contentDoc.getRootElement(); - return rootElement.valueOf(DOCUMENT_ELM_CONTENT_TYPE); - } - } - return getContentTypeClass(site, path); - } - - protected ContentItemTO loadContentItem(String site, String path) throws SiteNotFoundException { + protected ContentItemTO loadContentItem(String site, String path) throws ServiceLayerException { // TODO: SJ: Refactor such that the populate of non-XML is also a method in 3.1+ ContentItemTO item = createNewContentItemTO(site, path); @@ -584,19 +511,18 @@ protected ContentItemTO loadContentItem(String site, String path) throws SiteNot return item; } - protected void loadContentTypeProperties(String site, ContentItemTO item, String contentType) throws SiteNotFoundException { + protected void loadContentTypeProperties(String site, ContentItemTO item, String contentTypeId) throws ServiceLayerException { // TODO: SJ: Refactor in 2.7.x if (item.isFolder()) { item.setContentType(CONTENT_TYPE_FOLDER); } else { // TODO: Use constants instead of string literals - if (contentType != null && !contentType.equals(CONTENT_TYPE_FOLDER) && !contentType.equals("asset") && - !contentType.equals(CONTENT_TYPE_UNKNOWN)) { - ContentTypeConfigTO config = servicesConfig.getContentTypeConfig(site, contentType); - if (config != null) { - item.setForm(config.getForm()); - item.setFormPagePath(config.getFormPath()); - item.setPreviewable(config.isPreviewable()); + if (contentTypeId != null && !contentTypeId.equals(CONTENT_TYPE_FOLDER) && !contentTypeId.equals("asset") && + !contentTypeId.equals(CONTENT_TYPE_UNKNOWN)) { + ContentType contentType = contentTypeService.getContentType(site, contentTypeId); + if (contentType != null) { + item.setForm(contentType.getId()); + item.setPreviewable(contentType.isPreviewable()); item.isPreviewable = item.previewable; } } else { @@ -755,9 +681,7 @@ public String getContentVersionAsString(@ValidateStringParam String site, return null; } - @Override - @Valid - public ContentItemTO createDummyDmContentItemForDeletedNode(@ValidateStringParam String site, + private ContentItemTO createDummyDmContentItemForDeletedNode(@ValidateStringParam String site, @ValidateSecurePathParam() String relativePath) throws SiteNotFoundException { // TODO: SJ: Think of another way to do this in 3.1+ @@ -835,33 +759,12 @@ protected static String getBrowserUri(String uri, String replacePattern, boolean return browserUri; } - @Override - @Valid - public String getContentTypeClass(@ValidateStringParam String site, String uri) throws SiteNotFoundException { - // TODO: SJ: This reads: if can't guess what it is, it's a page. This is to be replaced in 3.1+ - if (uri.endsWith(FILE_SEPARATOR + servicesConfig.getLevelDescriptorName(site))) { - return CONTENT_TYPE_LEVEL_DESCRIPTOR; - } else if (matchesPatterns(uri, servicesConfig.getPagePatterns(site))) { - return CONTENT_TYPE_PAGE; - } else if (matchesPatterns(uri, servicesConfig.getComponentPatterns(site))) { - return CONTENT_TYPE_COMPONENT; - } else if (matchesPatterns(uri, servicesConfig.getDocumentPatterns(site))) { - return CONTENT_TYPE_DOCUMENT; - } else if (matchesPatterns(uri, servicesConfig.getAssetPatterns(site))) { - return CONTENT_TYPE_ASSET; - } else if (matchesPatterns(uri, servicesConfig.getRenderingTemplatePatterns(site))) { - return CONTENT_TYPE_RENDERING_TEMPLATE; - } else if (StringUtils.startsWith(uri, contentTypeService.getConfigPath())) { - return CONTENT_TYPE_CONTENT_TYPE; - } else if (matchesPatterns(uri, List.of(CONTENT_TYPE_TAXONOMY_REGEX))) { - return CONTENT_TYPE_TAXONOMY; - } else if (matchesPatterns(uri, servicesConfig.getScriptsPatterns(site))) { - return CONTENT_TYPE_SCRIPT; - } else if (matchesPatterns(uri, servicesConfig.getConfigurationPatterns(site))) { - return CONTENT_TYPE_CONFIGURATION; - } + private String getContentTypeClass(@ValidateStringParam String site, String uri) throws SiteNotFoundException { + return ContentUtils.getContentTypeClass(servicesConfig, studioConfiguration, site, uri); + } - return CONTENT_TYPE_FILE; + protected String getContentTypesBasePath() { + return studioConfiguration.getProperty(CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_BASE_PATH); } @Override @@ -1019,10 +922,6 @@ public void setStudioConfiguration(StudioConfiguration studioConfiguration) { this.studioConfiguration = studioConfiguration; } - public void setContentTypeService(ContentTypeService contentTypeService) { - this.contentTypeService = contentTypeService; - } - public void setContentRepository(GitContentRepository contentRepository) { this.contentRepository = contentRepository; } @@ -1039,4 +938,7 @@ public void setPublishService(final PublishService publishService) { this.publishService = publishService; } + public void setContentTypeService(ContentTypeService contentTypeService) { + this.contentTypeService = contentTypeService; + } } diff --git a/src/main/java/org/craftercms/studio/impl/v1/service/content/ContentTypeServiceImpl.java b/src/main/java/org/craftercms/studio/impl/v1/service/content/ContentTypeServiceImpl.java deleted file mode 100644 index e912464bf9..0000000000 --- a/src/main/java/org/craftercms/studio/impl/v1/service/content/ContentTypeServiceImpl.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) 2007-2024 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.impl.v1.service.content; - -import jakarta.validation.Valid; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.craftercms.commons.validation.annotations.param.ValidateSecurePathParam; -import org.craftercms.commons.validation.annotations.param.ValidateStringParam; -import org.craftercms.studio.api.v1.constant.StudioConstants; -import org.craftercms.studio.api.v1.exception.ServiceLayerException; -import org.craftercms.studio.api.v1.exception.SiteNotFoundException; -import org.craftercms.studio.api.v1.service.configuration.ContentTypesConfig; -import org.craftercms.studio.api.v1.service.configuration.ServicesConfig; -import org.craftercms.studio.api.v1.service.content.ContentService; -import org.craftercms.studio.api.v1.service.content.ContentTypeService; -import org.craftercms.studio.api.v1.service.security.SecurityService; -import org.craftercms.studio.api.v1.to.ContentTypeConfigTO; -import org.craftercms.studio.api.v2.dal.security.NormalizedRole; -import org.craftercms.studio.api.v2.repository.GitContentRepository; -import org.craftercms.studio.api.v2.repository.RepositoryItem; -import org.craftercms.studio.api.v2.utils.StudioConfiguration; -import org.craftercms.studio.impl.v2.utils.security.SecurityUtils; -import org.dom4j.DocumentException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; - -import static java.lang.String.format; -import static org.craftercms.studio.api.v1.constant.StudioConstants.FILE_SEPARATOR; -import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_BASE_PATH; -import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_FILE_NAME; - -/** - * @author Dejan Brkic - */ -public class ContentTypeServiceImpl implements ContentTypeService { - - private static final Logger logger = LoggerFactory.getLogger(ContentTypeServiceImpl.class); - - protected ContentService contentService; - protected ServicesConfig servicesConfig; - protected ContentTypesConfig contentTypesConfig; - protected SecurityService securityService; - protected GitContentRepository contentRepository; - protected StudioConfiguration studioConfiguration; - - @Override - @Valid - public ContentTypeConfigTO getContentTypeForContent(@ValidateStringParam String site, - @ValidateSecurePathParam String path) - throws ServiceLayerException { - try { - String type = contentService.getItemContentType(site, path); - if (StringUtils.isEmpty(type)) { - throw new ServiceLayerException(format("No content type specified for '%s' in site '%s'", path, site)); - } - return servicesConfig.getContentTypeConfig(site, type); - } catch (DocumentException e) { - throw new ServiceLayerException(format("Failed to get content type for item at path '%s' site '%s'", path, site)); - } - } - - @Override - public boolean isUserAllowed(Collection userRoles, ContentTypeConfigTO item) { - if (item == null) { - logger.debug("No content type config provided for null item to limit user access, " + - "defaulting to permit the user"); - return true; - } - - Set allowedRoles = item.getAllowedRoles(); - logger.trace("Item '{}' allows roles '{}', checking against user roles '{}'", - item.getName(), allowedRoles, userRoles); - - if (CollectionUtils.isEmpty(allowedRoles)) { - logger.trace("User with roles '{}' is allowed access to '{}'", userRoles, item.getName()); - return true; - } - - boolean notAllowed = Collections.disjoint(userRoles, allowedRoles); - if (notAllowed) { - logger.debug("Item '{}' is not allowed for user with roles '{}'", - item.getName(), userRoles); - return false; - } - - logger.trace("User with roles '{}' is allowed access to '{}'", userRoles, item.getName()); - return true; - } - - @Override - @Valid - public ContentTypeConfigTO getContentType(@ValidateStringParam String site, - @ValidateStringParam String type) throws SiteNotFoundException { - return servicesConfig.getContentTypeConfig(site, type); - } - - @Override - @Valid - public List getAllContentTypes(@ValidateStringParam String site, - boolean searchable) throws ServiceLayerException { - return getAllContentTypes(site); - } - - @Override - @Valid - public List getAllowedContentTypesForPath(@ValidateStringParam String site, - @ValidateSecurePathParam - String relativePath) throws ServiceLayerException { - String user = SecurityUtils.getCurrentUsername(); - Collection userRoles = securityService.getUserRoles(site, user); - List allContentTypes = getAllContentTypes(site); - - if (CollectionUtils.isNotEmpty(allContentTypes)) { - List contentTypes = new ArrayList<>(); - for (ContentTypeConfigTO contentTypeConfig : allContentTypes) { - // check if the path matches one of includes paths - if (CollectionUtils.isNotEmpty(contentTypeConfig.getPathIncludes())) { - for (String pathIncludes : contentTypeConfig.getPathIncludes()) { - if (relativePath.matches(pathIncludes)) { - logger.trace("In site '{}' path '{}' matches '{}'", site, relativePath, pathIncludes); - boolean isMatch = true; - if (contentTypeConfig.getPathExcludes() != null) { - for (String excludePath : contentTypeConfig.getPathExcludes()) { - if (relativePath.matches(excludePath)) { - logger.trace("In site '{}' path '{}' matches an exclude path '{}'", - site, relativePath, excludePath); - isMatch = false; - break; - } - } - } - if (isMatch) { - // if a match is found, populate the content type information - addContentTypes(userRoles, contentTypeConfig, contentTypes); - } - } - } - } else if (CollectionUtils.isEmpty(contentTypeConfig.getPathExcludes())) { - addContentTypes(userRoles, contentTypeConfig, contentTypes); - } - } - return contentTypes; - } else { - logger.error("No content type path configuration is found for site '{}'", site); - return null; - } - } - - protected void addContentTypes(Collection userRoles, ContentTypeConfigTO config, - List contentTypes) { - boolean isAllowed = this.isUserAllowed(userRoles, config); - if (isAllowed) { - contentTypes.add(config); - } - } - - protected List getAllContentTypes(String site) throws ServiceLayerException { - String contentTypesRootPath = getConfigPath().replaceAll(StudioConstants.PATTERN_SITE, site); - - Collection folders = contentRepository.getContentChildren(site, contentTypesRootPath); - List contentTypes = new ArrayList<>(); - - if (folders == null) { - return contentTypes; - } - for (RepositoryItem folder : folders) { - String configPath = - folder.path() + FILE_SEPARATOR + folder.name() + FILE_SEPARATOR + getConfigFileName(); - if (contentService.contentExists(site, configPath)) { - ContentTypeConfigTO config = contentTypesConfig - .reloadConfiguration(site, - configPath.replace(contentTypesRootPath, "") - .replace(FILE_SEPARATOR + getConfigFileName(), "")); - if (config != null) { - contentTypes.add(config); - } - } - - reloadContentTypeConfigForChildren(site, folder, contentTypes); - } - return contentTypes; - } - - protected void reloadContentTypeConfigForChildren(String site, RepositoryItem node, - List contentTypes) throws ServiceLayerException { - String contentTypesRootPath = getConfigPath().replaceAll(StudioConstants.PATTERN_SITE, site); - String fullPath = node.path() + FILE_SEPARATOR + node.name(); - logger.debug("Get Content Type Config from site '{}' for children path '{}'", site, fullPath); - Collection folders = contentRepository.getContentChildren(site, fullPath); - if (folders == null) { - return; - } - for (RepositoryItem folder : folders) { - if (!folder.isFolder()) { - continue; - } - String configPath = - folder.path() + FILE_SEPARATOR + folder.name() + FILE_SEPARATOR + getConfigFileName(); - if (contentService.contentExists(site, configPath)) { - ContentTypeConfigTO config = contentTypesConfig - .reloadConfiguration(site, configPath - .replace(contentTypesRootPath, "") - .replace(FILE_SEPARATOR + getConfigFileName(), "")); - if (config != null) { - contentTypes.add(config); - } - } - // traverse the children file-folder structure - reloadContentTypeConfigForChildren(site, folder, contentTypes); - } - } - - public String getConfigPath() { - return studioConfiguration.getProperty(CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_BASE_PATH); - } - - public String getConfigFileName() { - return studioConfiguration.getProperty(CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_FILE_NAME); - } - - public void setContentService(ContentService contentService) { - this.contentService = contentService; - } - - public void setServicesConfig(ServicesConfig servicesConfig) { - this.servicesConfig = servicesConfig; - } - - @SuppressWarnings("unused") - public void setContentTypesConfig(ContentTypesConfig contentTypesConfig) { - this.contentTypesConfig = contentTypesConfig; - } - - public void setSecurityService(SecurityService securityService) { - this.securityService = securityService; - } - - public void setContentRepository(GitContentRepository contentRepository) { - this.contentRepository = contentRepository; - } - - public void setStudioConfiguration(StudioConfiguration studioConfiguration) { - this.studioConfiguration = studioConfiguration; - } -} diff --git a/src/main/java/org/craftercms/studio/impl/v1/service/content/DmPageNavigationOrderServiceImpl.java b/src/main/java/org/craftercms/studio/impl/v1/service/content/DmPageNavigationOrderServiceImpl.java index db9c2ea911..1065fda1df 100644 --- a/src/main/java/org/craftercms/studio/impl/v1/service/content/DmPageNavigationOrderServiceImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v1/service/content/DmPageNavigationOrderServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -21,7 +21,6 @@ import org.craftercms.studio.api.v1.constant.DmXmlConstants; import org.craftercms.studio.api.v1.dal.NavigationOrderSequence; import org.craftercms.studio.api.v1.dal.NavigationOrderSequenceMapper; -import org.craftercms.studio.api.v1.service.AbstractRegistrableService; import org.craftercms.studio.api.v1.service.GeneralLockService; import org.craftercms.studio.api.v1.service.content.ContentService; import org.craftercms.studio.api.v1.service.content.DmPageNavigationOrderService; @@ -42,8 +41,7 @@ import static org.craftercms.studio.api.v2.utils.StudioConfiguration.PAGE_NAVIGATION_ORDER_INCREMENT; -public class DmPageNavigationOrderServiceImpl extends AbstractRegistrableService - implements DmPageNavigationOrderService { +public class DmPageNavigationOrderServiceImpl implements DmPageNavigationOrderService { private static final Logger logger = LoggerFactory.getLogger(DmPageNavigationOrderServiceImpl.class); @@ -53,11 +51,6 @@ public class DmPageNavigationOrderServiceImpl extends AbstractRegistrableService protected NavigationOrderSequenceMapper navigationOrderSequenceMapper; protected RetryingDatabaseOperationFacade retryingDatabaseOperationFacade; - @Override - public void register() { - this._servicesManager.registerService(DmPageNavigationOrderService.class, this); - } - @Override @Valid public double getNewNavOrder(@ValidateStringParam String site, @@ -185,42 +178,22 @@ public void copy(String siteId, String sourcePath, String targetPath) { retryingDatabaseOperationFacade.retry(() -> navigationOrderSequenceMapper.copy(siteId, sourcePath, targetPath)); } - public GeneralLockService getGeneralLockService() { - return generalLockService; - } - public void setGeneralLockService(GeneralLockService generalLockService) { this.generalLockService = generalLockService; } - public ContentService getContentService() { - return contentService; - } - public void setContentService(ContentService contentService) { this.contentService = contentService; } - public StudioConfiguration getStudioConfiguration() { - return studioConfiguration; - } - public void setStudioConfiguration(StudioConfiguration studioConfiguration) { this.studioConfiguration = studioConfiguration; } - public NavigationOrderSequenceMapper getNavigationOrderSequenceMapper() { - return navigationOrderSequenceMapper; - } - public void setNavigationOrderSequenceMapper(NavigationOrderSequenceMapper navigationOrderSequenceMapper) { this.navigationOrderSequenceMapper = navigationOrderSequenceMapper; } - public RetryingDatabaseOperationFacade getRetryingDatabaseOperationFacade() { - return retryingDatabaseOperationFacade; - } - public void setRetryingDatabaseOperationFacade(RetryingDatabaseOperationFacade retryingDatabaseOperationFacade) { this.retryingDatabaseOperationFacade = retryingDatabaseOperationFacade; } diff --git a/src/main/java/org/craftercms/studio/impl/v1/service/dependency/RegexDependencyResolver.java b/src/main/java/org/craftercms/studio/impl/v1/service/dependency/RegexDependencyResolver.java index fab1feae0e..bb8057bf6b 100644 --- a/src/main/java/org/craftercms/studio/impl/v1/service/dependency/RegexDependencyResolver.java +++ b/src/main/java/org/craftercms/studio/impl/v1/service/dependency/RegexDependencyResolver.java @@ -18,10 +18,11 @@ import org.apache.commons.collections4.CollectionUtils; import org.craftercms.studio.api.v1.exception.ServiceLayerException; -import org.craftercms.studio.api.v1.service.content.ContentService; +import org.craftercms.studio.api.v1.exception.SiteNotFoundException; import org.craftercms.studio.api.v1.service.dependency.DependencyResolver; import org.craftercms.studio.api.v1.to.DependencyResolverConfigTO; import org.craftercms.studio.api.v2.service.config.ConfigurationService; +import org.craftercms.studio.api.v2.service.content.ContentService; import org.craftercms.studio.api.v2.utils.StudioConfiguration; import org.dom4j.Document; import org.dom4j.Element; @@ -38,6 +39,7 @@ import static org.craftercms.studio.api.v1.constant.StudioConstants.MODULE_STUDIO; import static org.craftercms.studio.api.v2.utils.StudioConfiguration.*; import static org.craftercms.studio.api.v2.utils.StudioUtils.matchesPatterns; +import static org.craftercms.studio.impl.v1.util.ContentUtils.convertStreamToString; import static org.springframework.web.util.HtmlUtils.htmlUnescape; public class RegexDependencyResolver implements DependencyResolver { @@ -58,7 +60,7 @@ public Map> resolve(String site, String path) { logger.debug("Determine the item type site '{}' path '{}'", site, path); DependencyResolverConfigTO.ItemType itemType = getItemTypeResolverConfig(site, path, config); if (itemType != null) { - String content = contentService.getContentAsString(site, path); + String content = convertStreamToString(contentService.getContent(site, path)); if (content != null) { Map dependencyTypes = itemType.getDependencyTypes(); @@ -224,7 +226,7 @@ private DependencyResolverConfigTO.ItemType getItemTypeResolverConfig(String sit } private Map> getDependencies(String site, String path, String content, Map dependencyTypes) { + DependencyResolverConfigTO.DependencyType> dependencyTypes) throws SiteNotFoundException { Map> toRet = new HashMap<>(); logger.debug("Get the dependencies for site '{}' path '{}'", site, path); for (Map.Entry dependencyTypeEntry : diff --git a/src/main/java/org/craftercms/studio/impl/v1/service/security/SecurityServiceImpl.java b/src/main/java/org/craftercms/studio/impl/v1/service/security/SecurityServiceImpl.java index 4a3989d8ab..a254ff8859 100644 --- a/src/main/java/org/craftercms/studio/impl/v1/service/security/SecurityServiceImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v1/service/security/SecurityServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -28,9 +28,7 @@ import org.craftercms.studio.api.v1.exception.ServiceLayerException; import org.craftercms.studio.api.v1.exception.SiteNotFoundException; import org.craftercms.studio.api.v1.exception.security.UserNotFoundException; -import org.craftercms.studio.api.v1.service.content.ContentTypeService; import org.craftercms.studio.api.v1.service.security.SecurityService; -import org.craftercms.studio.api.v1.to.ContentTypeConfigTO; import org.craftercms.studio.api.v1.to.PermissionsConfigTO; import org.craftercms.studio.api.v2.dal.Group; import org.craftercms.studio.api.v2.dal.User; @@ -40,16 +38,13 @@ import org.craftercms.studio.api.v2.service.security.UserService; import org.craftercms.studio.api.v2.utils.StudioConfiguration; import org.craftercms.studio.impl.v2.utils.DateUtils; -import org.craftercms.studio.impl.v2.utils.security.SecurityUtils; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.security.core.Authentication; import java.util.*; -import java.util.stream.Collectors; import static org.craftercms.studio.api.v1.constant.SecurityConstants.*; import static org.craftercms.studio.api.v1.constant.StudioConstants.*; @@ -65,17 +60,11 @@ public class SecurityServiceImpl implements SecurityService { private static final Logger logger = LoggerFactory.getLogger(SecurityServiceImpl.class); - protected ContentTypeService contentTypeService; protected StudioConfiguration studioConfiguration; protected UserService userService; protected ConfigurationService configurationService; protected Cache cache; - @Override - public String getCurrentUser() { - return SecurityUtils.getCurrentUsername(); - } - @Override @Valid public Map getUserProfile(@ValidateStringParam String user) @@ -102,25 +91,6 @@ public Set getUserPermissions(@ValidateStringParam final String site, @V // resolve the permission permissions = populateUserPermissions(site, path, roles, permissionsConfig); logger.trace("Check if the user is allowed to edit the content in site '{}' path '{}' user '{}' ", site, path, user); - - // TODO: SJ: refactor the code below if it's still in use, otherwise remove - if (path.indexOf("/site") == 0) { // If it's content a file - try { - ContentTypeConfigTO config = contentTypeService.getContentTypeForContent(site, path); - boolean isAllowed = contentTypeService.isUserAllowed(roles, config); - if (!isAllowed) { - logger.trace("User '{}' is not permitted to access site '{}' path '{}', add " + - "permission '{}'", user, site, path, StudioConstants.PERMISSION_VALUE_NOT_ALLOWED); - // If no default role is set - permissions.add(StudioConstants.PERMISSION_VALUE_NOT_ALLOWED); - return permissions; - } - } catch (ServiceLayerException e) { - // TODO: SJ: Is this really a debug? - logger.debug("Failed to get content type in site '{}' path '{}'. Skip user role check for " + - "user '{}'", site, path, user, e); - } - } } PermissionsConfigTO globalRolesConfig = loadGlobalRolesConfiguration(); @@ -215,15 +185,6 @@ protected void addUserRoles(Set roles, String site, String user) } } - @Override - @Valid - public Set getUserRoles(@ValidateStringParam final String site) { - return getUserRoles(site, SecurityUtils.getCurrentUsername()) - .stream() - .map(NormalizedRole::toString) - .collect(Collectors.toSet()); - } - @Override public Collection getUserRoles(@ValidateStringParam final String site, @ValidateStringParam String user) { @@ -485,11 +446,6 @@ public boolean isSiteAdmin(@ValidateStringParam String username, String site) { return toRet; } - @Override - public Authentication getAuthentication() { - return SecurityUtils.getAuthentication(); - } - @Override @Valid public List getUserGlobalRoles(long userId, @ValidateStringParam String username) @@ -531,10 +487,6 @@ public String getGlobalPermissionsFileName() { return studioConfiguration.getProperty(CONFIGURATION_GLOBAL_PERMISSION_MAPPINGS_FILE_NAME); } - public void setContentTypeService(ContentTypeService contentTypeService) { - this.contentTypeService = contentTypeService; - } - public void setStudioConfiguration(StudioConfiguration studioConfiguration) { this.studioConfiguration = studioConfiguration; } diff --git a/src/main/java/org/craftercms/studio/impl/v1/service/site/SiteServiceImpl.java b/src/main/java/org/craftercms/studio/impl/v1/service/site/SiteServiceImpl.java deleted file mode 100644 index 8fa262a1e8..0000000000 --- a/src/main/java/org/craftercms/studio/impl/v1/service/site/SiteServiceImpl.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.impl.v1.service.site; - -import jakarta.validation.Valid; -import org.apache.ibatis.session.SqlSessionFactory; -import org.craftercms.commons.entitlements.validator.EntitlementValidator; -import org.craftercms.commons.validation.annotations.param.ValidateStringParam; -import org.craftercms.studio.api.v1.dal.SiteFeed; -import org.craftercms.studio.api.v1.dal.SiteFeedMapper; -import org.craftercms.studio.api.v1.exception.ServiceLayerException; -import org.craftercms.studio.api.v1.exception.security.UserNotFoundException; -import org.craftercms.studio.api.v1.service.content.ContentService; -import org.craftercms.studio.api.v1.service.site.SiteService; -import org.craftercms.studio.api.v2.dal.RetryingDatabaseOperationFacade; -import org.craftercms.studio.api.v2.dal.UserDAO; -import org.craftercms.studio.api.v2.deployment.Deployer; -import org.craftercms.studio.api.v2.repository.GitContentRepository; -import org.craftercms.studio.api.v2.service.audit.AuditService; -import org.craftercms.studio.api.v2.service.config.ConfigurationService; -import org.craftercms.studio.api.v2.service.item.ItemService; -import org.craftercms.studio.api.v2.service.security.GroupService; -import org.craftercms.studio.api.v2.service.security.UserService; -import org.craftercms.studio.api.v2.service.site.SitesService; -import org.craftercms.studio.api.v2.upgrade.StudioUpgradeManager; -import org.craftercms.studio.api.v2.utils.StudioConfiguration; -import org.craftercms.studio.impl.v2.utils.security.SecurityUtils; -import org.jspecify.annotations.NonNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Note: consider renaming - * A site in Crafter Studio is currently the name for a WEM project being managed. - * This service provides access to site configuration - * - * @author russdanner - */ -public class SiteServiceImpl implements SiteService, ApplicationContextAware { - - private final static Logger logger = LoggerFactory.getLogger(SiteServiceImpl.class); - - protected Deployer deployer; - protected ContentService contentService; - protected GitContentRepository contentRepository; - protected GroupService groupService; - protected UserService userService; - protected StudioUpgradeManager upgradeManager; - protected StudioConfiguration studioConfiguration; - protected SitesService sitesServiceInternal; - protected AuditService auditService; - protected ConfigurationService configurationService; - protected ItemService itemService; - protected ApplicationContext applicationContext; - - @Autowired - protected SiteFeedMapper siteFeedMapper; - - protected EntitlementValidator entitlementValidator; - - protected org.craftercms.studio.api.v2.service.dependency.DependencyService dependencyServiceInternal; - protected RetryingDatabaseOperationFacade retryingDatabaseOperationFacade; - - protected UserDAO userDao; - - protected SqlSessionFactory sqlSessionFactory; - - @Override - @Valid - public boolean exists(@ValidateStringParam String site) { - return siteFeedMapper.exists(site) > 0; - } - - @Override - @Valid - public int getSitesPerUserTotal(@ValidateStringParam String username) - throws UserNotFoundException, ServiceLayerException { - if (userService.userExists(username)) { - Map params = new HashMap<>(); - params.put("username", username); - return siteFeedMapper.getSitesPerUserQueryTotal(params); - } else { - throw new UserNotFoundException(); - } - } - - @Override - @Valid - public List getSitesPerUser(int start, - int number) - throws UserNotFoundException, ServiceLayerException { - return getSitesPerUser(SecurityUtils.getCurrentUsername(), start, number); - } - - @Override - @Valid - public List getSitesPerUser(@ValidateStringParam String username, - int start, - int number) - throws UserNotFoundException, ServiceLayerException { - if (userService.userExists(username)) { - Map params = new HashMap<>(); - params.put("username", username); - params.put("start", start); - params.put("number", number); - List siteIds = siteFeedMapper.getSitesPerUserQuery(params); - List toRet = new ArrayList<>(); - if (siteIds != null && !siteIds.isEmpty()) { - params = new HashMap<>(); - params.put("siteids", siteIds); - toRet = siteFeedMapper.getSitesPerUserData(params); - } - return toRet; - } else { - throw new UserNotFoundException(); - } - } - - @Override - public void setApplicationContext(@NonNull ApplicationContext applicationContext) { - this.applicationContext = applicationContext; - } - - public void setContentService(ContentService contentService) { - this.contentService = contentService; - } - - public void setContentRepository(GitContentRepository repo) { - contentRepository = repo; - } - - public void setStudioConfiguration(StudioConfiguration studioConfiguration) { - this.studioConfiguration = studioConfiguration; - } - - public void setDeployer(Deployer deployer) { - this.deployer = deployer; - } - - @SuppressWarnings("unused") - public void setEntitlementValidator(final EntitlementValidator entitlementValidator) { - this.entitlementValidator = entitlementValidator; - } - - @SuppressWarnings("unused") - public void setGroupService(GroupService groupService) { - this.groupService = groupService; - } - - public void setUserService(UserService userService) { - this.userService = userService; - } - - @SuppressWarnings("unused") - public void setUpgradeManager(final StudioUpgradeManager upgradeManager) { - this.upgradeManager = upgradeManager; - } - - @SuppressWarnings("unused") - public void setSitesServiceInternal(SitesService sitesServiceInternal) { - this.sitesServiceInternal = sitesServiceInternal; - } - - public void setAuditService(AuditService auditService) { - this.auditService = auditService; - } - - public void setConfigurationService(ConfigurationService configurationService) { - this.configurationService = configurationService; - } - - public void setItemService(ItemService itemService) { - this.itemService = itemService; - } - - @SuppressWarnings("unused") - public void setDependencyServiceInternal(org.craftercms.studio.api.v2.service.dependency.DependencyService dependencyServiceInternal) { - this.dependencyServiceInternal = dependencyServiceInternal; - } - - public void setRetryingDatabaseOperationFacade(RetryingDatabaseOperationFacade retryingDatabaseOperationFacade) { - this.retryingDatabaseOperationFacade = retryingDatabaseOperationFacade; - } - - @SuppressWarnings("unused") - public void setUserDao(UserDAO userDao) { - this.userDao = userDao; - } - - @SuppressWarnings("unused") - public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { - this.sqlSessionFactory = sqlSessionFactory; - } -} diff --git a/src/main/java/org/craftercms/studio/impl/v1/util/ContentFormatUtils.java b/src/main/java/org/craftercms/studio/impl/v1/util/ContentFormatUtils.java deleted file mode 100644 index b9e09d9266..0000000000 --- a/src/main/java/org/craftercms/studio/impl/v1/util/ContentFormatUtils.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.craftercms.studio.impl.v1.util; - -import java.text.SimpleDateFormat; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.util.TimeZone; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * util methods for parsing/converting data - * - * @author hyanghee - */ -public class ContentFormatUtils { - - private static final Logger LOGGER = LoggerFactory.getLogger(ContentFormatUtils.class); - - /** - * model date format constants - **/ - public static final String DATE_PATTERN_TIMEZONE_GMT = "GMT"; - - /** - * parse the given date using the model date format and the timezone - * - * @param format - * @param dateStr - * @return timeZone - */ - public static ZonedDateTime parseDate(SimpleDateFormat format, String dateStr, String timeZone) { - ZonedDateTime retDate = null; - - if (format != null && dateStr != null) { - if (StringUtils.isEmpty(timeZone)) { - format.setTimeZone(TimeZone.getTimeZone(DATE_PATTERN_TIMEZONE_GMT)); - } else { - format.setTimeZone(TimeZone.getTimeZone(timeZone)); - } - - retDate = ZonedDateTime.parse(dateStr, DateTimeFormatter.ISO_DATE_TIME); - } else { - LOGGER.error("Requested date format with null args dateStr: " + dateStr + " using format: " + format); - } - - return retDate; - } - - /** - * get a boolean value given a string - * - * @param str - * @return boolean value - */ - public static boolean getBooleanValue(String str) { - return Boolean.parseBoolean(str); - } - - /** - * get integer value - * - * @param str - * @return int value - */ - public static int getIntValue(String str) { - try { - return Integer.parseInt(str); - } catch (NumberFormatException e) { - LOGGER.error("failed to get a number from " + str, e); - return -1; - } - } -} diff --git a/src/main/java/org/craftercms/studio/impl/v1/util/ContentUtils.java b/src/main/java/org/craftercms/studio/impl/v1/util/ContentUtils.java index d9b6daf140..77d605aa84 100644 --- a/src/main/java/org/craftercms/studio/impl/v1/util/ContentUtils.java +++ b/src/main/java/org/craftercms/studio/impl/v1/util/ContentUtils.java @@ -21,6 +21,7 @@ import org.craftercms.studio.api.v1.constant.StudioConstants; import org.craftercms.studio.api.v1.exception.SiteNotFoundException; import org.craftercms.studio.api.v1.service.configuration.ServicesConfig; +import org.craftercms.studio.api.v2.utils.StudioConfiguration; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; @@ -36,10 +37,10 @@ import static java.lang.String.format; import static java.nio.charset.StandardCharsets.UTF_8; import static org.apache.commons.io.FilenameUtils.getFullPathNoEndSeparator; -import static org.apache.commons.lang3.StringUtils.removeEnd; import static org.apache.commons.lang3.Strings.CS; import static org.craftercms.studio.api.v1.constant.DmConstants.SLASH_INDEX_FILE; import static org.craftercms.studio.api.v1.constant.StudioConstants.*; +import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_BASE_PATH; import static org.craftercms.studio.api.v2.utils.StudioUtils.matchesPatterns; @@ -123,7 +124,7 @@ public static String convertStreamToString(InputStream stream) throws IOExceptio * @return path of the parent item */ public static String getParentUrl(String path) { - return getFullPathNoEndSeparator(removeEnd(path, SLASH_INDEX_FILE)); + return getFullPathNoEndSeparator(CS.removeEnd(path, SLASH_INDEX_FILE)); } /** @@ -277,4 +278,51 @@ public static String getPreviewUrl(ServicesConfig servicesConfig, String site, S } return browserUri; } + + /** + * Get content type class for given site and uri. + * It will default to {@link org.craftercms.studio.api.v1.constant.StudioConstants#CONTENT_TYPE_FILE} if + * the path does not match any content type pattern. + * + * @param servicesConfig {@link ServicesConfig} instance to get the configured patterns for the site + * @param studioConfiguration {@link StudioConfiguration} instance to get the configured content types base + * @param site the site id + * @param uri the content uri + * @return the content type class + * @throws SiteNotFoundException if site is not found + */ + public static String getContentTypeClass(ServicesConfig servicesConfig, StudioConfiguration studioConfiguration, + String site, String uri) throws SiteNotFoundException { + if (uri.endsWith(FILE_SEPARATOR + servicesConfig.getLevelDescriptorName(site))) { + return CONTENT_TYPE_LEVEL_DESCRIPTOR; + } + if (matchesPatterns(uri, servicesConfig.getPagePatterns(site))) { + return CONTENT_TYPE_PAGE; + } + if (matchesPatterns(uri, servicesConfig.getComponentPatterns(site))) { + return CONTENT_TYPE_COMPONENT; + } + if (matchesPatterns(uri, servicesConfig.getDocumentPatterns(site))) { + return CONTENT_TYPE_DOCUMENT; + } + if (matchesPatterns(uri, servicesConfig.getAssetPatterns(site))) { + return CONTENT_TYPE_ASSET; + } + if (matchesPatterns(uri, servicesConfig.getRenderingTemplatePatterns(site))) { + return CONTENT_TYPE_RENDERING_TEMPLATE; + } + if (CS.startsWith(uri, studioConfiguration.getProperty(CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_BASE_PATH))) { + return CONTENT_TYPE_CONTENT_TYPE; + } + if (matchesPatterns(uri, List.of(CONTENT_TYPE_TAXONOMY_REGEX))) { + return CONTENT_TYPE_TAXONOMY; + } + if (matchesPatterns(uri, servicesConfig.getScriptsPatterns(site))) { + return CONTENT_TYPE_SCRIPT; + } + if (matchesPatterns(uri, servicesConfig.getConfigurationPatterns(site))) { + return CONTENT_TYPE_CONFIGURATION; + } + return CONTENT_TYPE_FILE; + } } diff --git a/src/main/java/org/craftercms/studio/impl/v1/util/SessionTokenUtils.java b/src/main/java/org/craftercms/studio/impl/v1/util/SessionTokenUtils.java deleted file mode 100644 index 921ad0d926..0000000000 --- a/src/main/java/org/craftercms/studio/impl/v1/util/SessionTokenUtils.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.craftercms.studio.impl.v1.util; - -import org.springframework.security.crypto.codec.Hex; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -public class SessionTokenUtils { - - public static String createToken(String username, int sessionTimeout) { - long expires = System.currentTimeMillis() + 1000L * 60 * sessionTimeout; - - StringBuilder tokenBuilder = new StringBuilder(); - tokenBuilder.append(username); - tokenBuilder.append(":"); - tokenBuilder.append(expires); - tokenBuilder.append(":"); - tokenBuilder.append(computeSignature(username, expires)); - - return tokenBuilder.toString(); - } - - - public static String computeSignature(String username, long expires) { - StringBuilder signatureBuilder = new StringBuilder(); - signatureBuilder.append(username); - signatureBuilder.append(":"); - signatureBuilder.append(expires); - - MessageDigest digest; - try { - digest = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e) { - throw new IllegalStateException("No MD5 algorithm available!"); - } - - return new String(Hex.encode(digest.digest(signatureBuilder.toString().getBytes()))); - } - - - public static String getUserNameFromToken(String authToken) { - if (null == authToken) { - return null; - } - - String[] parts = authToken.split(":"); - return parts[0]; - } - - - public static boolean validateToken(String authToken, String username) { - String[] parts = authToken.split(":"); - long expires = Long.parseLong(parts[1]); - String signature = parts[2]; - - if (expires < System.currentTimeMillis()) { - return false; - } - - return signature.equals(computeSignature(username, expires)); - } -} diff --git a/src/main/java/org/craftercms/studio/impl/v1/web/security/access/StudioAbstractAccessDecisionVoter.java b/src/main/java/org/craftercms/studio/impl/v1/web/security/access/StudioAbstractAccessDecisionVoter.java index 54a4364c22..9255c163dc 100644 --- a/src/main/java/org/craftercms/studio/impl/v1/web/security/access/StudioAbstractAccessDecisionVoter.java +++ b/src/main/java/org/craftercms/studio/impl/v1/web/security/access/StudioAbstractAccessDecisionVoter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -18,15 +18,14 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.craftercms.studio.api.v1.dal.SiteFeed; import org.craftercms.studio.api.v1.exception.ServiceLayerException; import org.craftercms.studio.api.v1.exception.SiteNotFoundException; import org.craftercms.studio.api.v1.exception.security.UserNotFoundException; import org.craftercms.studio.api.v1.service.security.SecurityService; -import org.craftercms.studio.api.v1.service.site.SiteService; import org.craftercms.studio.api.v2.dal.User; import org.craftercms.studio.api.v2.service.security.UserService; -import org.craftercms.studio.api.v2.utils.StudioConfiguration; +import org.craftercms.studio.api.v2.service.site.SitesService; +import org.craftercms.studio.model.Site; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.access.AccessDecisionVoter; @@ -48,8 +47,7 @@ public abstract class StudioAbstractAccessDecisionVoter implements AccessDecisio public static final String DEFAULT_PERMISSION_VOTER_PATH = ""; protected SecurityService securityService; - protected StudioConfiguration studioConfiguration; - protected SiteService siteService; + protected SitesService siteService; protected UserService userService; @Override @@ -66,11 +64,10 @@ public int vote(Authentication authentication, Object object, Collection collect protected boolean isSiteMember(String siteId, User currentUser) { try { - int total = siteService.getSitesPerUserTotal(currentUser.getUsername()); - List sitesFeed = siteService.getSitesPerUser(currentUser.getUsername(), 0, total); + List userSites = userService.getUserSites(-1, currentUser.getUsername()); Set sites = new HashSet<>(); - for (SiteFeed site : sitesFeed) { + for (Site site : userSites) { sites.add(site.getSiteId()); } @@ -90,18 +87,7 @@ protected boolean hasPermission(String siteId, String path, String user, String (CollectionUtils.isNotEmpty(userPermissions) && userPermissions.contains(permission)); } - protected boolean hasAnyPermission(String siteId, String path, String user, Set permissions) throws SiteNotFoundException { - Set userPermissions = securityService.getUserPermissions(siteId, path, user); - return CollectionUtils.isEmpty(permissions) || - (CollectionUtils.isNotEmpty(userPermissions) - && CollectionUtils.containsAny(userPermissions, permissions)); - } - - public void setStudioConfiguration(StudioConfiguration studioConfiguration) { - this.studioConfiguration = studioConfiguration; - } - - public void setSiteService(SiteService siteService) { + public void setSiteService(SitesService siteService) { this.siteService = siteService; } diff --git a/src/main/java/org/craftercms/studio/impl/v2/repository/GitContentRepositoryImpl.java b/src/main/java/org/craftercms/studio/impl/v2/repository/GitContentRepositoryImpl.java index 1123018a8e..4431b7d5b0 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/repository/GitContentRepositoryImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v2/repository/GitContentRepositoryImpl.java @@ -1559,49 +1559,6 @@ public String createFolder(String siteId, String folderPath) throws ServiceLayer } } - @Override - @SuppressWarnings("ResultOfMethodCallIgnored") - public String createFolder(String siteId, String path, String name) throws ServiceLayerException, UserNotFoundException { - // SJ: Git doesn't care about empty folders, so we will create the folders and put a 0 byte file in them - String gitLockKey = helper.getSandboxRepoLockKey(siteId, true); - generalLockService.lock(gitLockKey); - try { - Path emptyFilePath = Paths.get(path, name, EMPTY_FILE); - Repository repo = helper.getRepositoryForWrite(siteId); - - // Create basic file - File file = new File(repo.getDirectory().getParent(), emptyFilePath.toString()); - - // Create parent folders - File folder = file.getParentFile(); - // Does the folder ever exist here? We are about to create it - folder.mkdirs(); - - // Create the file - if (!file.createNewFile()) { - throw new ServiceLayerException(format("Failed to write empty file to folder '%s' for site '%s'", emptyFilePath, siteId)); - } - - helper.addFiles(repo, siteId, emptyFilePath.toString()); - - String commitId = helper.commitFiles(repo, siteId, - helper.getCommitMessage(REPO_CREATE_FOLDER_COMMIT_MESSAGE) - .replaceAll(PATTERN_SITE, siteId) - .replaceAll(PATTERN_PATH, path + FILE_SEPARATOR + name), - helper.getCurrentUserIdent(), emptyFilePath.toString()); - persistCommit(siteId, commitId); - return commitId; - } catch (ServiceLayerException | UserNotFoundException e) { - logger.error("Failed to create folder '{}' in site '{}'", name, siteId, e); - throw e; - } catch (IOException e) { - logger.error("Failed to create folder '{}' in site '{}'", name, siteId, e); - throw new ServiceLayerException(format("Failed to create folder '%s' in site '%s'", name, siteId), e); - } finally { - generalLockService.unlock(gitLockKey); - } - } - /** * Create empty files in the new folders and add the paths to the index * Notice that this method assumes the folders already exist in the repository. diff --git a/src/main/java/org/craftercms/studio/impl/v2/repository/blob/BlobAwareContentRepository.java b/src/main/java/org/craftercms/studio/impl/v2/repository/blob/BlobAwareContentRepository.java index 45862f178e..7d54d207c4 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/repository/blob/BlobAwareContentRepository.java +++ b/src/main/java/org/craftercms/studio/impl/v2/repository/blob/BlobAwareContentRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -283,24 +283,6 @@ public String writeContent(String site, String path, InputStream content) throws } } - @Override - public String createFolder(String site, String path, String name) throws ServiceLayerException, UserNotFoundException { - logger.debug("Create folder in site '{}' path '{}'", site, path); - try { - StudioBlobStore store = getBlobStore(site, path); - if (store != null) { - store.createFolder(site, normalize(path), name); - } - } catch (BlobStoreConfigurationMissingException e) { - logger.debug("No blob store configuration found for site '{}', " + - "will create folder '{}' in the local repository", site, path); - } catch (Exception e) { - logger.error("Failed to create folder in site '{}' path '{}'", site, path, e); - throw e; - } - return localRepository.createFolder(site, path, name); - } - @Override public String createFolder(String site, String path) throws ServiceLayerException, UserNotFoundException { logger.debug("Create folder in site '{}' path '{}'", site, path); diff --git a/src/main/java/org/craftercms/studio/impl/v2/service/content/ContentServiceImpl.java b/src/main/java/org/craftercms/studio/impl/v2/service/content/ContentServiceImpl.java index 36795bf3ed..aecb5fb68b 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/service/content/ContentServiceImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v2/service/content/ContentServiceImpl.java @@ -100,18 +100,6 @@ public DeleteContentResult deleteContent(@SiteId String siteId, return contentServiceInternal.deleteContent(siteId, paths, publishTitle, publishComment); } - @Override - @RequireSiteReady - @HasPermission(type = DefaultPermission.class, action = PERMISSION_GET_CHILDREN) - public GetChildrenResult getChildrenByPath(@SiteId String siteId, - @ProtectedResourceId(PATH_RESOURCE_ID) String path, String locale, - String keyword, List systemTypes, List excludes, - String sortStrategy, String order, int offset, int limit) - throws ServiceLayerException, UserNotFoundException { - return contentServiceInternal.getChildrenByPath(siteId, path, locale, keyword, systemTypes, excludes, - sortStrategy, order, offset, limit); - } - @Override @RequireSiteReady @HasPermission(type = CompositePermission.class, action = PERMISSION_GET_CHILDREN) @@ -305,21 +293,6 @@ public WriteContentResult createFolder(@SiteId String siteId, @ActionTargetPath return contentServiceInternal.createFolder(siteId, path); } - @Override - @RequireSiteReady - @HasPermission(type = DefaultPermission.class, action = PERMISSION_CONTENT_READ) - public String getContentTypeClass(@SiteId String site, @ContentPath String uri) throws SiteNotFoundException { - return contentServiceInternal.getContentTypeClass(site, uri); - } - - @Override - @RequireSiteReady - @RequireContentExists - @HasPermission(type = DefaultPermission.class, action = PERMISSION_PUBLISH_GET_QUEUE) - public void assertNotInWorkflow(@SiteId String siteId, List paths, boolean includeChildren) throws ServiceLayerException { - contentServiceInternal.assertNotInWorkflow(siteId, paths, includeChildren); - } - @Override @RequireSiteReady @RequireContentExists diff --git a/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentServiceInternalImpl.java b/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentServiceInternalImpl.java index db0941372c..2856980517 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentServiceInternalImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentServiceInternalImpl.java @@ -43,7 +43,6 @@ import org.craftercms.studio.api.v1.service.GeneralLockService; import org.craftercms.studio.api.v1.service.configuration.ServicesConfig; import org.craftercms.studio.api.v1.service.content.DmPageNavigationOrderService; -import org.craftercms.studio.api.v1.to.CopyDependencyConfigTO; import org.craftercms.studio.api.v2.content.ContentLifecycle; import org.craftercms.studio.api.v2.content.LifecycleContent; import org.craftercms.studio.api.v2.content.LifecycleContent.ContentLifecycleItem; @@ -70,6 +69,7 @@ import org.craftercms.studio.api.v2.service.audit.ActivityStreamService; import org.craftercms.studio.api.v2.service.audit.AuditService; import org.craftercms.studio.api.v2.service.content.ContentService; +import org.craftercms.studio.api.v2.service.content.ContentTypeService; import org.craftercms.studio.api.v2.service.dependency.DependencyService; import org.craftercms.studio.api.v2.service.item.ItemService; import org.craftercms.studio.api.v2.service.publish.PublishService; @@ -83,6 +83,8 @@ import org.craftercms.studio.impl.v2.utils.db.DBUtils; import org.craftercms.studio.impl.v2.utils.spring.ContentResource; import org.craftercms.studio.model.AuthenticatedUser; +import org.craftercms.studio.model.contentType.ContentType; +import org.craftercms.studio.model.contentType.CopyDependency; import org.craftercms.studio.model.history.ItemVersion; import org.craftercms.studio.model.history.RepositoryVersion; import org.craftercms.studio.model.rest.Person; @@ -143,7 +145,8 @@ import static org.craftercms.studio.api.v2.event.workflow.WorkflowEvent.WorkFlowEventType.DIRECT_PUBLISH; import static org.craftercms.studio.api.v2.utils.DalUtils.MY_BATIS_QUERY_BATCH_SIZE; import static org.craftercms.studio.api.v2.utils.DalUtils.mapSortFields; -import static org.craftercms.studio.api.v2.utils.StudioConfiguration.*; +import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_GLOBAL_SYSTEM_SITE; +import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONTENT_ITEM_EDITABLE_TYPES; import static org.craftercms.studio.api.v2.utils.StudioUtils.*; import static org.craftercms.studio.impl.v1.repository.git.GitContentRepositoryConstants.IGNORE_FILES; import static org.craftercms.studio.impl.v1.util.ContentUtils.*; @@ -198,6 +201,7 @@ public class ContentServiceInternalImpl implements ContentService, ApplicationEv private final ActivityStreamService activityStreamService; private final EntitlementValidator entitlementValidator; private final SqlSessionFactory sqlSessionFactory; + private final ContentTypeService contentTypeService; @ConstructorProperties({"transactionManager", "studioConfiguration", "siteService", "retryingDatabaseOperationFacade", "publishService", @@ -206,7 +210,8 @@ public class ContentServiceInternalImpl implements ContentService, ApplicationEv "contentRepository", "contentLifecycle", "auditService", "assetLifecycle", "servicesConfig", "activityStreamService", - "entitlementValidator", "sqlSessionFactory"}) + "entitlementValidator", "sqlSessionFactory", + "contentTypeService"}) public ContentServiceInternalImpl(PlatformTransactionManager transactionManager, StudioConfiguration studioConfiguration, SitesService siteService, RetryingDatabaseOperationFacade retryingDatabaseOperationFacade, PublishService publishService, @@ -217,7 +222,8 @@ public ContentServiceInternalImpl(PlatformTransactionManager transactionManager, GitContentRepository contentRepository, ContentLifecycle contentLifecycle, AuditService auditService, ContentLifecycle assetLifecycle, ServicesConfig servicesConfig, ActivityStreamService activityStreamService, - EntitlementValidator entitlementValidator, SqlSessionFactory sqlSessionFactory) { + EntitlementValidator entitlementValidator, SqlSessionFactory sqlSessionFactory, + ContentTypeService contentTypeService) { this.transactionManager = transactionManager; this.studioConfiguration = studioConfiguration; this.siteService = siteService; @@ -237,6 +243,7 @@ public ContentServiceInternalImpl(PlatformTransactionManager transactionManager, this.activityStreamService = activityStreamService; this.entitlementValidator = entitlementValidator; this.sqlSessionFactory = sqlSessionFactory; + this.contentTypeService = contentTypeService; } @Override @@ -249,9 +256,23 @@ public boolean shallowContentExists(String siteId, String path) { return contentRepository.shallowContentExists(siteId, path); } - @Override - public GetChildrenResult getChildrenByPath(String siteId, String path, String locale, String keyword, - List systemTypes, List excludes, String sortStrategy, + /** + * Get list of children for given path + * + * @param siteId site identifier + * @param path item path to children for + * @param locale filter children by locale + * @param keyword filter children by keyword + * @param systemTypes filter children by type + * @param excludes exclude items by path + * @param sortStrategy sort order + * @param order ascending or descending + * @param offset offset of the first child in the result + * @param limit number of children to return + * @return list of children + */ + protected GetChildrenResult getChildrenByPath(String siteId, String path, String locale, String keyword, + List systemTypes, List excludes, String sortStrategy, String order, int offset, int limit) throws ServiceLayerException, UserNotFoundException { if (!contentRepository.contentExists(siteId, path)) { @@ -652,10 +673,10 @@ protected T runWriteInTransaction(String transactionId, Integer isolationLev } } - protected WriteContentResult doWrite(final String siteId, final String path, - final InputStream content, final LifecycleOperation operation) + protected WriteContentResult doRevert(final String siteId, final String path, + final InputStream content) throws UserNotFoundException, AuthenticationException, ServiceLayerException { - return doWrite(siteId, path, content, operation, null); + return doWrite(siteId, path, content, REVERT, null); } protected WriteContentResult doWrite(final String siteId, final String path, @@ -795,7 +816,7 @@ public void revert(String siteId, String path, String commitId) throws ServiceLa logger.error("Failed to load content for revert at site '{}' path '{}' commit '{}'", siteId, path, commitId, e); throw new ServiceLayerException(format("Failed to load content for revert at site '%s' path '%s' commit '%s'", siteId, path, commitId), e); } - doWrite(siteId, path, content, REVERT); + doRevert(siteId, path, content); } @Override @@ -829,41 +850,6 @@ public WriteContentResult createFolder(String siteId, String path) throws Servic return writeContentResult; } - @Override - public String getContentTypeClass(String site, String uri) throws SiteNotFoundException { - if (uri.endsWith(FILE_SEPARATOR + servicesConfig.getLevelDescriptorName(site))) { - return CONTENT_TYPE_LEVEL_DESCRIPTOR; - } - if (matchesPatterns(uri, servicesConfig.getPagePatterns(site))) { - return CONTENT_TYPE_PAGE; - } - if (matchesPatterns(uri, servicesConfig.getComponentPatterns(site))) { - return CONTENT_TYPE_COMPONENT; - } - if (matchesPatterns(uri, servicesConfig.getDocumentPatterns(site))) { - return CONTENT_TYPE_DOCUMENT; - } - if (matchesPatterns(uri, servicesConfig.getAssetPatterns(site))) { - return CONTENT_TYPE_ASSET; - } - if (matchesPatterns(uri, servicesConfig.getRenderingTemplatePatterns(site))) { - return CONTENT_TYPE_RENDERING_TEMPLATE; - } - if (CS.startsWith(uri, studioConfiguration.getProperty(CONFIGURATION_SITE_CONTENT_TYPES_CONFIG_BASE_PATH))) { - return CONTENT_TYPE_CONTENT_TYPE; - } - if (matchesPatterns(uri, List.of(CONTENT_TYPE_TAXONOMY_REGEX))) { - return CONTENT_TYPE_TAXONOMY; - } - if (matchesPatterns(uri, servicesConfig.getScriptsPatterns(site))) { - return CONTENT_TYPE_SCRIPT; - } - if (matchesPatterns(uri, servicesConfig.getConfigurationPatterns(site))) { - return CONTENT_TYPE_CONFIGURATION; - } - return CONTENT_TYPE_FILE; - } - @Override public void processCreatedFiles(String siteId, User creator) throws ServiceLayerException { Site site = siteService.getSite(siteId); @@ -946,7 +932,7 @@ private void processCreatedFile(ItemDAO itemDao, DependencyDAO dependencyDao, Sq String label = FilenameUtils.getName(path); String contentTypeId = EMPTY; boolean disabled = false; - if (StringUtils.endsWith(path, XML_PATTERN)) { + if (CS.endsWith(path, XML_PATTERN)) { try { Document contentDoc = ContentUtils.convertStreamToXml(getContent(site.getSiteId(), path)); if (contentDoc != null) { @@ -964,8 +950,8 @@ private void processCreatedFile(ItemDAO itemDao, DependencyDAO dependencyDao, Sq } } String previewUrl = null; - if (StringUtils.startsWith(path, ROOT_PATTERN_PAGES) || - StringUtils.startsWith(path, ROOT_PATTERN_ASSETS)) { + if (CS.startsWith(path, ROOT_PATTERN_PAGES) || + CS.startsWith(path, ROOT_PATTERN_ASSETS)) { previewUrl = itemService.getBrowserUrl(site.getSiteId(), path); } long state = ItemState.NEW.value; @@ -985,7 +971,7 @@ private void processCreatedFile(ItemDAO itemDao, DependencyDAO dependencyDao, Sq .withLastPublishedOn(null) .withLabel(label) .withContentTypeId(contentTypeId) - .withSystemType(getContentTypeClass(site.getSiteId(), path)) + .withSystemType(getContentTypeClass(servicesConfig, studioConfiguration, site.getSiteId(), path)) .withMimeType(StudioUtils.getMimeType(FilenameUtils.getName(path))) .withLocaleCode(Locale.US.toString()) .withTranslationSourceId(null) @@ -1097,7 +1083,7 @@ protected void updateReferences(Element root, String oldDepPath, String newDepPa protected Map getCopyDependencyMapping(String siteId, String sourcePath, ContentItemIds oldContentIds, ContentItemIds newContentItemIds, Element root) - throws SiteNotFoundException { + throws ServiceLayerException { Map copyDependencies = new HashMap<>(); List itemSpecificDependencies = dependencyService.getItemSpecificDependencies(siteId, List.of(sourcePath)); for (LightItem itemSpecificDependency : itemSpecificDependencies) { @@ -1106,9 +1092,9 @@ protected Map getCopyDependencyMapping(String siteId, String sou copyDependencies.put(itemSpecificDependency.getPath(), replaceContentIdsInPath(depTargetPath, oldContentIds, newContentItemIds)); } - String contentType = readSingleDocumentNodeText(root, CONTENT_TYPE); - List copyDepConfigs = - servicesConfig.getCopyDependencyPatterns(siteId, contentType); + String contentTypeId = readSingleDocumentNodeText(root, CONTENT_TYPE); + ContentType contentType = contentTypeService.getContentType(siteId, contentTypeId); + List copyDepConfigs = contentType.getCopyDependencies(); if (copyDepConfigs.isEmpty()) { return copyDependencies; // No copy dependencies config to process @@ -1121,8 +1107,8 @@ protected Map getCopyDependencyMapping(String siteId, String sou continue; } copyDepConfigs.stream() - .filter(copyDepConfig -> dependencyPath.matches(copyDepConfig.getPattern())) - .map(CopyDependencyConfigTO::getTarget) + .filter(copyDepConfig -> dependencyPath.matches(copyDepConfig.pattern())) + .map(CopyDependency::target) .findAny() .map(t -> replaceContentIdsInPath(t, oldContentIds, newContentItemIds)) .ifPresent(t -> copyDependencies.put(dependencyPath, t)); @@ -1668,8 +1654,7 @@ public List getChildItems(final String siteId, final List pat return childItems; } - @Override - public void assertNotInWorkflow(final String siteId, final List paths, final boolean includeChildren) + protected void assertNotInWorkflow(final String siteId, final List paths, final boolean includeChildren) throws ServiceLayerException { Collection packagesForItems = publishService.getActivePackagesForItems(siteId, paths, includeChildren); if (CollectionUtils.isNotEmpty(packagesForItems)) { diff --git a/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentTypeServiceInternalImpl.java b/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentTypeServiceInternalImpl.java index b8c3fd95ec..2eccdc06bc 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentTypeServiceInternalImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v2/service/content/internal/ContentTypeServiceInternalImpl.java @@ -21,7 +21,6 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; -import org.craftercms.commons.lang.UrlUtils; import org.craftercms.studio.api.v1.exception.ContentNotFoundException; import org.craftercms.studio.api.v1.exception.ServiceLayerException; import org.craftercms.studio.api.v1.exception.SiteNotFoundException; @@ -48,6 +47,9 @@ import org.jspecify.annotations.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Lazy; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; @@ -71,6 +73,7 @@ import static org.apache.commons.lang3.RegExUtils.replaceAll; import static org.apache.commons.lang3.StringUtils.isNotEmpty; import static org.apache.commons.lang3.Strings.CI; +import static org.craftercms.commons.lang.UrlUtils.concat; import static org.craftercms.studio.api.v1.constant.GitRepositories.SANDBOX; import static org.craftercms.studio.api.v1.constant.StudioConstants.*; import static org.craftercms.studio.permissions.StudioPermissionsConstants.PERMISSION_CONTENT_CREATE; @@ -131,6 +134,9 @@ public ContentTypeServiceInternalImpl(SecurityService securityService, this.xmlMapper = new XmlMapper(); } + @Lazy + @Autowired + @Qualifier("contentServiceInternal") public void setContentService(ContentService contentService) { this.contentService = contentService; } @@ -225,8 +231,7 @@ private String getContentTypeFormPath(String contentTypeId) { * @throws ConfigurationException if there is any error reading the content type configuration */ protected ContentType loadContentType(String siteId, String contentTypeId) throws ConfigurationException, ContentNotFoundException { - InputStream configurationAsStream = contentService.getContent(siteId, getContentTypeFormPath(contentTypeId)); - try { + try (InputStream configurationAsStream = contentService.getContent(siteId, getContentTypeFormPath(contentTypeId))) { return xmlMapper.readValue(configurationAsStream, ContentType.class); } catch (IOException e) { throw new ConfigurationException(format("Failed to read content type configuration for content type '%s' in site '%s'", contentTypeId, siteId), e); @@ -276,7 +281,7 @@ public ImmutablePair getContentTypePreviewImage(String siteId, String filename = getContentTypePreviewImageFilename(siteId, contentTypeId); boolean hasPreviewImage = isNotEmpty(filename) && !filename.equals("undefined"); // form-definition could have undefined value for imageThumbnail if (hasPreviewImage) { - String previewImagePath = UrlUtils.concat(getContentTypePath(contentTypeId), filename); + String previewImagePath = concat(getContentTypePath(contentTypeId), filename); return (new ImmutablePair<>(previewImagePath, contentService.getContentAsResource(siteId, previewImagePath))); } @@ -285,8 +290,8 @@ public ImmutablePair getContentTypePreviewImage(String siteId, @Override public ImmutablePair getContentTypeFormController(String siteId, String contentTypeId) throws ServiceLayerException { - if (contentService.contentExists(siteId, UrlUtils.concat(getContentTypePath(contentTypeId), contentTypeDefinitionFilename))) { - String controllerPath = UrlUtils.concat(getContentTypePath(contentTypeId), formControllerFilePath); + if (contentService.contentExists(siteId, concat(getContentTypePath(contentTypeId), contentTypeDefinitionFilename))) { + String controllerPath = concat(getContentTypePath(contentTypeId), formControllerFilePath); return new ImmutablePair<>(controllerPath, contentService.getContentAsResource(siteId, controllerPath)); } diff --git a/src/main/java/org/craftercms/studio/impl/v2/service/item/internal/ItemServiceInternalImpl.java b/src/main/java/org/craftercms/studio/impl/v2/service/item/internal/ItemServiceInternalImpl.java index e1183e50df..8c85081fb2 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/service/item/internal/ItemServiceInternalImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v2/service/item/internal/ItemServiceInternalImpl.java @@ -30,16 +30,20 @@ import org.craftercms.studio.api.v1.service.configuration.ServicesConfig; import org.craftercms.studio.api.v2.dal.*; import org.craftercms.studio.api.v2.dal.item.ContentItem; -import org.craftercms.studio.api.v2.service.content.ContentService; +import org.craftercms.studio.api.v2.repository.GitContentRepository; import org.craftercms.studio.api.v2.service.item.ItemService; import org.craftercms.studio.api.v2.service.security.UserService; +import org.craftercms.studio.api.v2.utils.StudioConfiguration; import org.craftercms.studio.api.v2.utils.StudioUtils; import org.craftercms.studio.impl.v1.util.ContentUtils; import org.craftercms.studio.impl.v2.utils.DateUtils; import org.craftercms.studio.impl.v2.utils.security.SecurityUtils; import org.slf4j.Logger; -import java.util.*; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; import static java.util.Collections.emptyMap; import static org.apache.commons.collections4.CollectionUtils.isEmpty; @@ -47,6 +51,7 @@ import static org.craftercms.studio.api.v2.dal.ItemState.*; import static org.craftercms.studio.api.v2.utils.DalUtils.mapSortFields; import static org.craftercms.studio.api.v2.utils.StudioUtils.underDescriptorRoot; +import static org.craftercms.studio.impl.v1.util.ContentUtils.getContentTypeClass; import static org.slf4j.LoggerFactory.getLogger; public class ItemServiceInternalImpl implements ItemService { @@ -61,12 +66,12 @@ public class ItemServiceInternalImpl implements ItemService { private SiteDAO siteDao; private ItemDAO itemDao; private ServicesConfig servicesConfig; - private ContentService contentService; private GeneralLockService generalLockService; + private GitContentRepository contentRepository; private RetryingDatabaseOperationFacade retryingDatabaseOperationFacade; + private StudioConfiguration studioConfiguration; - @Override - public void upsertEntry(Item item) { + protected void upsertEntry(Item item) { retryingDatabaseOperationFacade.retry(() -> itemDao.upsertEntry(item)); } @@ -89,11 +94,6 @@ public void deleteItem(long siteId, String path, boolean removePageParentFolder) retryingDatabaseOperationFacade.retry(() -> itemDao.deleteBySiteAndPath(siteId, path, removePageParentFolder)); } - @Override - public void updateItem(Item item) { - retryingDatabaseOperationFacade.retry(() -> itemDao.updateItem(item)); - } - @Override public void setSystemProcessingBulk(String siteId, Collection paths, boolean isSystemProcessing) { if (isSystemProcessing) { @@ -117,22 +117,6 @@ private void resetStatesBySiteAndPathBulk(String siteId, Collection path } } - @Override - public void updateStateBits(String siteId, String path, long onStateBitMap, long offStateBitMap) { - List paths = new ArrayList<>(); - paths.add(path); - updateStatesBySiteAndPathBulk(siteId, paths, onStateBitMap, offStateBitMap); - } - - private void updateStatesBySiteAndPathBulk(String siteId, Collection paths, long onStateBitMap, - long offStateBitMap) { - if (CollectionUtils.isNotEmpty(paths)) { - Site site = siteDao.getSite(siteId); - retryingDatabaseOperationFacade.retry(() -> itemDao.updateStatesBySiteAndPathBulk(site.getId(), paths, - onStateBitMap, offStateBitMap)); - } - } - @Override public Item.Builder instantiateItem(String siteName, String path) { Item item = getItem(siteName, path); @@ -165,7 +149,7 @@ public void persistItemAfterCreate(String siteId, String path, String contentType = null; String localeCode = null; try { - var descriptor = contentService.getItem(siteId, path, false); + var descriptor = contentRepository.getItem(siteId, path, false); String disabledStr = descriptor.queryDescriptorValue(DISABLED); disabled = Boolean.parseBoolean(disabledStr); label = descriptor.queryDescriptorValue(INTERNAL_NAME_XPATH); @@ -188,11 +172,11 @@ public void persistItemAfterCreate(String siteId, String path, .withLastModifiedBy(userObj.getId()) .withLastModifiedOn(DateUtils.getCurrentTime()) .withLabel(label) - .withSystemType(contentService.getContentTypeClass(siteId, path)) + .withSystemType(getContentTypeClass(servicesConfig, studioConfiguration, siteId, path)) .withContentTypeId(contentType) .withMimeType(StudioUtils.getMimeType(path)) .withLocaleCode(localeCode) - .withSize(contentService.getContentSize(siteId, path)) + .withSize(contentRepository.getContentSize(siteId, path)) .withParentId(parentId) .build(); if (unlock) { @@ -219,7 +203,7 @@ public void persistItemAfterWrite(String siteId, String path, boolean unlock) String contentType = null; String localeCode = null; try { - var descriptor = contentService.getItem(siteId, path, false); + var descriptor = contentRepository.getItem(siteId, path, false); String disabledStr = descriptor.queryDescriptorValue(DISABLED); disabled = Boolean.parseBoolean(disabledStr); label = descriptor.queryDescriptorValue(INTERNAL_NAME_XPATH); @@ -240,11 +224,11 @@ public void persistItemAfterWrite(String siteId, String path, boolean unlock) .withLastModifiedBy(userObj.getId()) .withLastModifiedOn(DateUtils.getCurrentTime()) .withLabel(label) - .withSystemType(contentService.getContentTypeClass(siteId, path)) + .withSystemType(getContentTypeClass(servicesConfig, studioConfiguration, siteId, path)) .withContentTypeId(contentType) .withMimeType(StudioUtils.getMimeType(path)) .withLocaleCode(localeCode) - .withSize(contentService.getContentSize(siteId, path)) + .withSize(contentRepository.getContentSize(siteId, path)) .build(); if (unlock) { item.setState(ItemState.savedAndClosed(item.getState())); @@ -274,21 +258,6 @@ public void persistItemAfterCreateFolder(String siteId, String folderPath, Strin upsertEntry(item); } - @Override - public void persistItemAfterRenameContent(String siteId, String path, String name, String contentType) - throws ServiceLayerException, AuthenticationException { - User userObj = SecurityUtils.getCurrentUser(); - Item item = instantiateItem(siteId, path) - .withPreviewUrl(CONTENT_TYPE_FOLDER.equals(contentType) ? null : getBrowserUrl(siteId, path)) - .withLastModifiedBy(userObj.getId()) - .withLastModifiedOn(DateUtils.getCurrentTime()) - .withLabel(name) - .build(); - item.setState(ItemState.savedAndClosed(item.getState())); - item.setSystemType(contentType); - updateItem(item); - } - @Override public void moveItem(String siteId, String oldPath, String newPath, Long parentId, String label, long userId) throws SiteNotFoundException { @@ -462,9 +431,12 @@ public void setServicesConfig(ServicesConfig servicesConfig) { this.servicesConfig = servicesConfig; } - @SuppressWarnings("unused") - public void setContentService(ContentService contentService) { - this.contentService = contentService; + public void setContentRepository(GitContentRepository contentRepository) { + this.contentRepository = contentRepository; + } + + public void setStudioConfiguration(StudioConfiguration studioConfiguration) { + this.studioConfiguration = studioConfiguration; } public void setGeneralLockService(GeneralLockService generalLockService) { diff --git a/src/main/java/org/craftercms/studio/impl/v2/service/marketplace/internal/MarketplaceServiceInternalImpl.java b/src/main/java/org/craftercms/studio/impl/v2/service/marketplace/internal/MarketplaceServiceInternalImpl.java index 8392f8163d..479bab75a1 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/service/marketplace/internal/MarketplaceServiceInternalImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v2/service/marketplace/internal/MarketplaceServiceInternalImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -39,7 +39,6 @@ import org.craftercms.commons.rest.RestTemplate; import org.craftercms.studio.api.v1.constant.GitRepositories; import org.craftercms.studio.api.v1.exception.ContentNotFoundException; -import org.craftercms.studio.api.v1.exception.EnvironmentNotFoundException; import org.craftercms.studio.api.v1.exception.ServiceLayerException; import org.craftercms.studio.api.v1.exception.SiteNotFoundException; import org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryCredentialsException; @@ -49,14 +48,13 @@ import org.craftercms.studio.api.v1.exception.security.AuthenticationException; import org.craftercms.studio.api.v1.exception.security.UserNotFoundException; import org.craftercms.studio.api.v1.service.configuration.ServicesConfig; -import org.craftercms.studio.api.v1.service.content.ContentService; -import org.craftercms.studio.api.v1.service.site.SiteService; import org.craftercms.studio.api.v2.dal.item.LightItem; import org.craftercms.studio.api.v2.exception.MissingPluginParameterException; import org.craftercms.studio.api.v2.exception.configuration.ConfigurationException; import org.craftercms.studio.api.v2.exception.marketplace.*; import org.craftercms.studio.api.v2.repository.RetryingRepositoryOperationFacade; import org.craftercms.studio.api.v2.service.config.ConfigurationService; +import org.craftercms.studio.api.v2.service.content.ContentService; import org.craftercms.studio.api.v2.service.content.ContentTypeService; import org.craftercms.studio.api.v2.service.dependency.DependencyService; import org.craftercms.studio.api.v2.service.marketplace.*; @@ -121,6 +119,7 @@ import static org.craftercms.studio.api.v1.constant.StudioConstants.PATTERN_MODULE; import static org.craftercms.studio.api.v2.service.marketplace.Constants.SOURCE_GIT; import static org.craftercms.studio.api.v2.utils.StudioConfiguration.CONFIGURATION_SITE_CONFIG_BASE_PATH_PATTERN; +import static org.craftercms.studio.impl.v1.util.ContentUtils.convertStreamToString; import static org.craftercms.studio.impl.v2.utils.PluginUtils.*; import static org.craftercms.studio.impl.v2.utils.XsltUtils.executeTemplate; import static org.craftercms.studio.model.rest.sites.CreateSiteRequest.RemoteAuthentication.NONE; @@ -163,8 +162,6 @@ public class MarketplaceServiceInternalImpl implements MarketplaceService, Initi protected final InstanceService instanceService; - protected final SiteService siteService; - protected final SitesService sitesServiceInternal; protected final ContentService contentService; @@ -276,12 +273,12 @@ public class MarketplaceServiceInternalImpl implements MarketplaceService, Initi protected final ContentTypeService contentTypeService; - @ConstructorProperties({"instanceService", "siteService", "sitesServiceInternal", "contentService", + @ConstructorProperties({"instanceService", "sitesServiceInternal", "contentService", "studioConfiguration", "pluginDescriptorReader", "gitRepositoryHelper", "pluginDescriptorFilename", "templateCode", "templateComment", "retryingRepositoryOperationFacade", "dependencyService", "contentTypeService", "configurationService", "servicesConfig", "publishService"}) - public MarketplaceServiceInternalImpl(InstanceService instanceService, SiteService siteService, + public MarketplaceServiceInternalImpl(InstanceService instanceService, SitesService sitesServiceInternal, ContentService contentService, StudioConfiguration studioConfiguration, PluginDescriptorReader pluginDescriptorReader, @@ -293,7 +290,6 @@ public MarketplaceServiceInternalImpl(InstanceService instanceService, SiteServi ConfigurationService configurationService, ServicesConfig servicesConfig, PublishService publishService) { this.instanceService = instanceService; - this.siteService = siteService; this.sitesServiceInternal = sitesServiceInternal; this.contentService = contentService; this.studioConfiguration = studioConfiguration; @@ -838,7 +834,7 @@ public void removePlugin(String siteId, String pluginId, boolean force) throws S // commit all changes commitChanges(siteId, changedFiles, true, true, "Remove plugin " + pluginId); - } catch (IOException | GitAPIException | EnvironmentNotFoundException | + } catch (IOException | GitAPIException | SiteNotFoundException | TransformerException | UserNotFoundException | AuthenticationException e) { if (CollectionUtils.isNotEmpty(changedFiles)) { try { @@ -1068,7 +1064,7 @@ protected void performConfigurationWiring(Plugin plugin, String siteId, List files, - List changedFiles) throws IOException { + List changedFiles) throws IOException, ContentNotFoundException { List paths = files.stream().map(FileRecord::getPath).collect(toList()); String pluginPath = getPluginPath(plugin.getId()); String pluginIdComment = replace(templateComment, Map.of(PARAM_PLUGIN_ID, plugin.getId())); @@ -1083,14 +1079,14 @@ protected void performTemplateWiring(Plugin plugin, String siteId, List paths, String includePath, String includeComment, String pluginPath, List changedFiles) - throws IOException { + throws IOException, ContentNotFoundException { if (paths.contains(pluginPath)) { logger.debug("Detected the template '{}' in the plugin '{}' while installing in site '{}'", pluginPath, pluginId, siteId); String fileContent = EMPTY; if (contentService.contentExists(siteId, includePath)) { logger.debug("Site '{}' already has the template '{}', it will be updated", siteId, includePath); - fileContent = contentService.getContentAsString(siteId, includePath); + fileContent = convertStreamToString(contentService.getContent(siteId, includePath)); } else { logger.debug("Site '{}' does not have the template '{}', it will be created", siteId, includePath); } diff --git a/src/main/java/org/craftercms/studio/impl/v2/service/site/SitesServiceImpl.java b/src/main/java/org/craftercms/studio/impl/v2/service/site/SitesServiceImpl.java index 22c8059dd7..300fe1f692 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/service/site/SitesServiceImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v2/service/site/SitesServiceImpl.java @@ -48,8 +48,7 @@ import java.util.Collection; import java.util.List; -import static org.apache.commons.lang3.StringUtils.isBlank; -import static org.craftercms.studio.api.v1.dal.SiteFeed.STATE_LOCKED; +import static org.apache.commons.lang3.StringUtils.defaultIfBlank; import static org.craftercms.studio.permissions.StudioPermissionsConstants.*; public class SitesServiceImpl implements SitesService { @@ -81,14 +80,18 @@ public String getBlueprintLocation(String blueprintId) throws ServiceLayerExcept @HasPermission(type = DefaultPermission.class, action = PERMISSION_EDIT_SITE) public void updateSite(@SiteId String siteId, String name, String description) throws SiteNotFoundException, SiteAlreadyExistsException, InvalidParametersException { - if (isBlank(name) && isBlank(description)) { + + String normalizedName = defaultIfBlank(name, null); + String normalizedDescription = defaultIfBlank(description, null); + + if (normalizedDescription == null && normalizedName == null) { throw new InvalidParametersException("The request needs to include a name or a description"); } - sitesServiceInternal.updateSite(siteId, name, description); + sitesServiceInternal.updateSite(siteId, normalizedName, normalizedDescription); } @Override - @RequireSiteState(value = STATE_LOCKED) + @RequireSiteState(value = Site.State.LOCKED) @HasPermission(type = DefaultPermission.class, action = PERMISSION_EDIT_SITE) public void unlockSite(@SiteId String siteId) throws SiteNotFoundException, InvalidSiteStateException { sitesServiceInternal.unlockSite(siteId); diff --git a/src/main/java/org/craftercms/studio/impl/v2/service/site/internal/SitesServiceInternalImpl.java b/src/main/java/org/craftercms/studio/impl/v2/service/site/internal/SitesServiceInternalImpl.java index 207d8c978a..adf7517635 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/service/site/internal/SitesServiceInternalImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v2/service/site/internal/SitesServiceInternalImpl.java @@ -26,7 +26,6 @@ import org.craftercms.commons.plugin.model.PluginDescriptor; import org.craftercms.commons.upgrade.exception.UpgradeException; import org.craftercms.studio.api.v1.constant.StudioConstants; -import org.craftercms.studio.api.v1.dal.SiteFeedMapper; import org.craftercms.studio.api.v1.exception.*; import org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryCredentialsException; import org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryException; @@ -114,7 +113,6 @@ public class SitesServiceInternalImpl implements SitesService, ApplicationContex private final PluginDescriptorReader descriptorReader; private StudioBlobAwareContentRepository blobAwareRepository; private final StudioConfiguration studioConfiguration; - private final SiteFeedMapper siteFeedMapper; private final SiteDAO siteDao; private final RetryingDatabaseOperationFacade retryingDatabaseOperationFacade; private final Deployer deployer; @@ -131,22 +129,19 @@ public class SitesServiceInternalImpl implements SitesService, ApplicationContex private ApplicationContext applicationContext; @ConstructorProperties({"descriptorReader", - "studioConfiguration", "siteFeedMapper", - "siteDao", + "studioConfiguration", "siteDao", "retryingDatabaseOperationFacade", "deployer", "auditService", "taskManager", "entitlementValidator", "userService"}) public SitesServiceInternalImpl(PluginDescriptorReader descriptorReader, - StudioConfiguration studioConfiguration, SiteFeedMapper siteFeedMapper, - SiteDAO siteDao, + StudioConfiguration studioConfiguration, SiteDAO siteDao, RetryingDatabaseOperationFacade retryingDatabaseOperationFacade, Deployer deployer, AuditService auditService, TaskManager taskManager, EntitlementValidator entitlementValidator, UserService userService) { this.descriptorReader = descriptorReader; this.studioConfiguration = studioConfiguration; - this.siteFeedMapper = siteFeedMapper; this.siteDao = siteDao; this.retryingDatabaseOperationFacade = retryingDatabaseOperationFacade; this.deployer = deployer; @@ -227,10 +222,10 @@ protected PluginDescriptor loadDescriptor(RepositoryItem folder) { @Override public void updateSite(String siteId, String name, String description) throws SiteNotFoundException, SiteAlreadyExistsException { - if (isNotEmpty(name) && siteFeedMapper.isNameUsed(siteId, name)) { + if (isNotEmpty(name) && siteDao.isNameUsed(siteId, name)) { throw new SiteAlreadyExistsException("A site with name " + name + " already exists"); } - int updated = retryingDatabaseOperationFacade.retry(() -> siteFeedMapper.updateSite(siteId, name, description)); + int updated = retryingDatabaseOperationFacade.retry(() -> siteDao.updateSite(siteId, name, description)); if (updated != 1) { throw new SiteNotFoundException(); } @@ -521,7 +516,7 @@ public TaskProgress getPublishingTaskProgress(S @Override public void duplicate(String sourceSiteId, String siteId, String siteName, String description, String sandboxBranch, boolean readOnlyBlobStores) throws ServiceLayerException { - if (isNotEmpty(siteName) && siteFeedMapper.isNameUsed(siteId, siteName)) { + if (isNotEmpty(siteName) && siteDao.isNameUsed(siteId, siteName)) { throw new SiteAlreadyExistsException(format("A site with name '%s' already exists", siteName)); } diff --git a/src/main/java/org/craftercms/studio/impl/v2/service/system/internal/SystemPropertiesServiceInternalImpl.java b/src/main/java/org/craftercms/studio/impl/v2/service/system/internal/SystemPropertiesServiceInternalImpl.java index 854468d31e..17ab24c502 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/service/system/internal/SystemPropertiesServiceInternalImpl.java +++ b/src/main/java/org/craftercms/studio/impl/v2/service/system/internal/SystemPropertiesServiceInternalImpl.java @@ -16,7 +16,6 @@ package org.craftercms.studio.impl.v2.service.system.internal; -import org.craftercms.studio.api.v1.exception.security.AuthenticationException; import org.craftercms.studio.api.v2.dal.*; import org.craftercms.studio.api.v2.dal.system.SystemPropertiesDAO; import org.craftercms.studio.api.v2.dal.system.SystemProperty; diff --git a/src/main/java/org/craftercms/studio/impl/v2/sync/SyncFromRepositoryTask.java b/src/main/java/org/craftercms/studio/impl/v2/sync/SyncFromRepositoryTask.java index 62c8dde8f1..1a6fadf6f7 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/sync/SyncFromRepositoryTask.java +++ b/src/main/java/org/craftercms/studio/impl/v2/sync/SyncFromRepositoryTask.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -92,6 +92,7 @@ import static org.craftercms.studio.api.v2.utils.StudioConfiguration.REPO_SYNC_CANCELLED_PACKAGE_COMMENT; import static org.craftercms.studio.api.v2.utils.StudioUtils.getPublishPackageLockKey; import static org.craftercms.studio.impl.v1.repository.git.GitContentRepositoryConstants.*; +import static org.craftercms.studio.impl.v1.util.ContentUtils.getContentTypeClass; /** * Listens to {@link SyncFromRepoEvent} events and performs the sync from repository. @@ -593,7 +594,7 @@ private void processCreate(ItemDAO itemDao, DependencyDAO dependencyDao, SqlSess .withLastPublishedOn(null) .withLabel(metadata.label) .withContentTypeId(metadata.contentTypeId) - .withSystemType(contentService.getContentTypeClass(site.getSiteId(), repoOperation.getPath())) + .withSystemType(getContentTypeClass(servicesConfig, studioConfiguration, site.getSiteId(), repoOperation.getPath())) .withMimeType(StudioUtils.getMimeType(FilenameUtils.getName(repoOperation.getPath()))) .withLocaleCode(Locale.US.toString()) .withTranslationSourceId(null) @@ -633,7 +634,7 @@ private void processUpdate(ItemDAO itemDao, DependencyDAO dependencyDao, SqlSess updateItemRow(itemDao, site.getId(), repoOperation.getPath(), metadata.previewUrl, onStateBitMap, offStateBitmap, user.getId(), repoOperation.getDateTime(), metadata.label, metadata.contentTypeId, - contentService.getContentTypeClass(site.getSiteId(), repoOperation.getPath()), + getContentTypeClass(servicesConfig, studioConfiguration, site.getSiteId(), repoOperation.getPath()), StudioUtils.getMimeType(FilenameUtils.getName(repoOperation.getPath())), contentRepository.getContentSize(site.getSiteId(), repoOperation.getPath())); @@ -672,7 +673,7 @@ private void processMove(ItemDAO itemDao, DependencyDAO dependencyDao, SqlSessio updateItemRow(itemDao, site.getId(), repoOperation.getPath(), metadata.previewUrl, onStateBitMap, offStateBitmap, user.getId(), repoOperation.getDateTime(), metadata.label, metadata.contentTypeId, - contentService.getContentTypeClass(site.getSiteId(), repoOperation.getPath()), + getContentTypeClass(servicesConfig, studioConfiguration, site.getSiteId(), repoOperation.getMoveToPath()), StudioUtils.getMimeType(FilenameUtils.getName(repoOperation.getPath())), contentRepository.getContentSize(site.getSiteId(), repoOperation.getPath())); diff --git a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/AbstractContentUpgradeOperation.java b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/AbstractContentUpgradeOperation.java index a803a5f35e..2f5ea0a85d 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/AbstractContentUpgradeOperation.java +++ b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/AbstractContentUpgradeOperation.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -16,31 +16,35 @@ package org.craftercms.studio.impl.v2.upgrade.operations.site; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; -import java.nio.file.*; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.LinkedList; -import java.util.List; - import org.apache.commons.collections.CollectionUtils; import org.apache.commons.configuration2.HierarchicalConfiguration; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.craftercms.commons.lang.RegexUtils; import org.craftercms.commons.upgrade.exception.UpgradeException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.craftercms.studio.api.v2.utils.StudioConfiguration; import org.craftercms.studio.impl.v2.upgrade.StudioUpgradeContext; import org.craftercms.studio.impl.v2.upgrade.operations.AbstractUpgradeOperation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.LinkedList; +import java.util.List; import static java.util.Collections.singletonList; +import static org.apache.commons.collections4.CollectionUtils.emptyIfNull; import static org.apache.commons.collections4.CollectionUtils.isEmpty; -import static org.apache.commons.lang3.StringUtils.removeStart; +import static org.apache.commons.lang3.Strings.CS; /** * Base implementation of {@link org.craftercms.commons.upgrade.UpgradeOperation} for all site content upgrades @@ -80,15 +84,12 @@ public void doExecute(final StudioUpgradeContext context) throws UpgradeExceptio // This is required to support upgrades in config pipelines if (isEmpty(includedPaths) && StringUtils.isNotEmpty(context.getCurrentConfigPath())) { Path repo = context.getRepositoryPath(); //TODO: Check if parent is needed - includedPaths = singletonList(repo.resolve(removeStart(context.getCurrentConfigPath(), //TODO: Check if path is ok - File.separator))); + includedPaths = singletonList(repo.resolve(CS.removeStart(context.getCurrentConfigPath(), //TODO: Check if path is ok + File.separator))); } - List filteredPaths = filterPaths(context, includedPaths); - if (CollectionUtils.isNotEmpty(filteredPaths)) { - for (Path file : filteredPaths) { - updateFile(context, file); - trackChangedFiles(context.getRelativePath(file)); - } + for (Path file : emptyIfNull(includedPaths)) { + updateFile(context, file); + trackChangedFiles(context.getRelativePath(file)); } } catch (IOException e) { throw new UpgradeException("Error reading content for site " + site, e); @@ -112,37 +113,6 @@ protected List findIncludedPaths(StudioUpgradeContext context) throws IOEx return null; } - /** - * Filters the given list checking if the files match the update conditions - * - * @param context the current upgrade context - * @param matchedPaths the list of files to filter - * @return the filtered list of files - * @throws UpgradeException if there is any error filtering the files - */ - protected List filterPaths(StudioUpgradeContext context, List matchedPaths) throws UpgradeException { - if (CollectionUtils.isNotEmpty(matchedPaths)) { - List filteredPaths = new LinkedList<>(); - for (Path path : matchedPaths) { - if (shouldBeUpdated(context, path)) { - filteredPaths.add(path); - } - } - return filteredPaths; - } - return null; - } - - /** - * Indicates if the given file should be updated by this class - * - * @param context the current upgrade context - * @param file the file to check - * @return true if the file should be updated - * @throws UpgradeException if there is any error checking the file - */ - protected abstract boolean shouldBeUpdated(StudioUpgradeContext context, Path file) throws UpgradeException; - /** * Performs any needed updates on the content of the given file * diff --git a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/ConfigEncryptionUpgradeOperation.java b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/ConfigEncryptionUpgradeOperation.java index b07db0da01..415a68f604 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/ConfigEncryptionUpgradeOperation.java +++ b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/ConfigEncryptionUpgradeOperation.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -45,11 +45,6 @@ public ConfigEncryptionUpgradeOperation(StudioConfiguration studioConfiguration, this.textEncryptor = textEncryptor; } - @Override - protected boolean shouldBeUpdated(StudioUpgradeContext context, Path file) { - return true; - } - @Override protected void updateFile(StudioUpgradeContext context, Path path) throws UpgradeException { try { diff --git a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/ContentTypeControllerUpgradeOperation.java b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/ContentTypeControllerUpgradeOperation.java index db00d974c5..2d7ac92929 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/ContentTypeControllerUpgradeOperation.java +++ b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/ContentTypeControllerUpgradeOperation.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2025 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -60,11 +60,6 @@ public void afterPropertiesSet() throws Exception { defaultScript = Files.readString(Path.of(defaultScriptResource.getURI())); } - @Override - protected boolean shouldBeUpdated(StudioUpgradeContext context, Path file) { - return true; - } - @Override protected void updateFile(StudioUpgradeContext context, Path path) throws UpgradeException { try { diff --git a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/FindAndReplaceUpgradeOperation.java b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/FindAndReplaceUpgradeOperation.java index 1a9f57ecd7..7958131545 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/FindAndReplaceUpgradeOperation.java +++ b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/FindAndReplaceUpgradeOperation.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -69,11 +69,6 @@ protected void doInit(final HierarchicalConfiguration config) { replacement = config.getString(CONFIG_KEY_REPLACEMENT); } - @Override - protected boolean shouldBeUpdated(StudioUpgradeContext context, Path file) { - return true; - } - @Override protected void updateFile(StudioUpgradeContext context, Path path) throws UpgradeException { String content = readFile(path); diff --git a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/MultiFindAndReplaceUpgradeOperation.java b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/MultiFindAndReplaceUpgradeOperation.java index accf611025..3e0d9cc7c5 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/MultiFindAndReplaceUpgradeOperation.java +++ b/src/main/java/org/craftercms/studio/impl/v2/upgrade/operations/site/MultiFindAndReplaceUpgradeOperation.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2023 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -74,11 +74,6 @@ protected void doInit(final HierarchicalConfiguration config) { ruleConfigs.forEach(rule -> rules.add(new Rule(rule.getString(CONFIG_KEY_PATTERN), rule.getString(CONFIG_KEY_REPLACEMENT)))); } - @Override - protected boolean shouldBeUpdated(StudioUpgradeContext context, Path file) { - return true; - } - @Override protected void updateFile(StudioUpgradeContext context, Path path) throws UpgradeException { String content = readFile(path); diff --git a/src/main/java/org/craftercms/studio/impl/v2/utils/spring/ContentResource.java b/src/main/java/org/craftercms/studio/impl/v2/utils/spring/ContentResource.java index 4102a010c2..90228ab0d2 100644 --- a/src/main/java/org/craftercms/studio/impl/v2/utils/spring/ContentResource.java +++ b/src/main/java/org/craftercms/studio/impl/v2/utils/spring/ContentResource.java @@ -49,7 +49,7 @@ public class ContentResource extends AbstractResource { */ protected String path; - public ContentResource(final org.craftercms.studio.api.v2.service.content.ContentService contentService, final String site, final String path) { + public ContentResource(final ContentService contentService, final String site, final String path) { this.contentService = contentService; this.site = site; this.path = path; diff --git a/src/main/java/org/craftercms/studio/model/contentType/ContentType.java b/src/main/java/org/craftercms/studio/model/contentType/ContentType.java index d35c794488..c8571fbc63 100644 --- a/src/main/java/org/craftercms/studio/model/contentType/ContentType.java +++ b/src/main/java/org/craftercms/studio/model/contentType/ContentType.java @@ -118,12 +118,18 @@ public void setNoThumbnail(boolean noThumbnail) { } public Collection getPathIncludes() { + if (pathIncludeExcludes == null) { + return emptyList(); + } return emptyIfNull(pathIncludeExcludes.includes()).stream() .map(PathPattern::getPattern) .toList(); } public Collection getPathExcludes() { + if (pathIncludeExcludes == null) { + return emptyList(); + } return emptyIfNull(pathIncludeExcludes.excludes()).stream() .map(PathPattern::getPattern) .toList(); diff --git a/src/main/java/org/craftercms/studio/model/contentType/DeleteDependency.java b/src/main/java/org/craftercms/studio/model/contentType/DeleteDependency.java index 8e3b002497..ea7f9bcfe9 100644 --- a/src/main/java/org/craftercms/studio/model/contentType/DeleteDependency.java +++ b/src/main/java/org/craftercms/studio/model/contentType/DeleteDependency.java @@ -17,7 +17,6 @@ package org.craftercms.studio.model.contentType; import com.fasterxml.jackson.annotation.JsonAlias; -import com.fasterxml.jackson.annotation.JsonProperty; /** * Represents a delete dependency for a content type. diff --git a/src/main/java/org/craftercms/studio/model/rest/contentType/DeleteContentTypeRequest.java b/src/main/java/org/craftercms/studio/model/rest/contentType/DeleteContentTypeRequest.java index b66b1537d8..756ec3add9 100644 --- a/src/main/java/org/craftercms/studio/model/rest/contentType/DeleteContentTypeRequest.java +++ b/src/main/java/org/craftercms/studio/model/rest/contentType/DeleteContentTypeRequest.java @@ -16,13 +16,11 @@ package org.craftercms.studio.model.rest.contentType; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.craftercms.commons.validation.annotations.param.ValidConfigurationPath; /** * Request for deleting a content-type. */ -@JsonIgnoreProperties public class DeleteContentTypeRequest { @ValidConfigurationPath protected String contentType; diff --git a/src/main/java/org/craftercms/studio/permissions/CompositePermissionResolverImpl.java b/src/main/java/org/craftercms/studio/permissions/CompositePermissionResolverImpl.java index 481e92d01f..61f23d38aa 100644 --- a/src/main/java/org/craftercms/studio/permissions/CompositePermissionResolverImpl.java +++ b/src/main/java/org/craftercms/studio/permissions/CompositePermissionResolverImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2024 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -50,10 +50,6 @@ public CompositePermissionResolverImpl(SecurityService securityService, StudioCo this.studioConfiguration = studioConfiguration; } - public StudioConfiguration getStudioConfiguration() { - return studioConfiguration; - } - @Override public Permission getGlobalPermission(String username) throws PermissionException { return getPermission(username, Collections.emptyMap()); diff --git a/src/main/java/org/craftercms/studio/permissions/PermissionResolverImpl.java b/src/main/java/org/craftercms/studio/permissions/PermissionResolverImpl.java index 2582ce2216..7fa9d2df26 100644 --- a/src/main/java/org/craftercms/studio/permissions/PermissionResolverImpl.java +++ b/src/main/java/org/craftercms/studio/permissions/PermissionResolverImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2024 Crafter Software Corporation. All Rights Reserved. + * Copyright (C) 2007-2026 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by @@ -52,10 +52,6 @@ public PermissionResolverImpl(final SecurityService securityService, final Studi this.studioConfiguration = studioConfiguration; } - public StudioConfiguration getStudioConfiguration() { - return studioConfiguration; - } - @Override public Permission getGlobalPermission(String username) throws PermissionException { return getPermission(username, Collections.emptyMap()); diff --git a/src/main/resources/crafter/studio/database-context.xml b/src/main/resources/crafter/studio/database-context.xml index 0de65062d8..b59f5e276d 100644 --- a/src/main/resources/crafter/studio/database-context.xml +++ b/src/main/resources/crafter/studio/database-context.xml @@ -140,11 +140,6 @@ - - - - - diff --git a/src/main/resources/crafter/studio/database/mybatis-config.xml b/src/main/resources/crafter/studio/database/mybatis-config.xml index d4142efe25..2ff54d3d98 100644 --- a/src/main/resources/crafter/studio/database/mybatis-config.xml +++ b/src/main/resources/crafter/studio/database/mybatis-config.xml @@ -1,5 +1,5 @@ @@ -83,33 +76,13 @@ - + - - - - - - - - - - - - - - - - - - - - @@ -122,7 +95,6 @@ - @@ -131,7 +103,6 @@ - @@ -144,25 +115,7 @@ - - - - - - - - - - - - - - - - - - + @@ -358,7 +311,6 @@ class="org.craftercms.studio.impl.v2.service.site.internal.SitesServiceInternalImpl"> - @@ -411,6 +363,7 @@ + @@ -448,8 +401,6 @@ value="#{studioConfiguration.getProperty('studio.configuration.contentType.formControllerFilePath')}" /> - - @@ -497,9 +448,10 @@ - + + @@ -525,13 +477,6 @@ - - - - - - @@ -915,48 +860,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -986,7 +889,7 @@ - + @@ -1043,17 +946,6 @@ - - - - - - - - - - - @@ -1062,13 +954,6 @@ - - - - - - - @@ -1187,8 +1072,8 @@ - + diff --git a/src/main/resources/org/craftercms/studio/api/v1/dal/DependencyMapper.xml b/src/main/resources/org/craftercms/studio/api/v1/dal/DependencyMapper.xml deleted file mode 100644 index 96e37af212..0000000000 --- a/src/main/resources/org/craftercms/studio/api/v1/dal/DependencyMapper.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/main/resources/org/craftercms/studio/api/v1/dal/SiteFeedMapper.xml b/src/main/resources/org/craftercms/studio/api/v1/dal/SiteFeedMapper.xml deleted file mode 100644 index 31143444d9..0000000000 --- a/src/main/resources/org/craftercms/studio/api/v1/dal/SiteFeedMapper.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - UPDATE site - - name = #{name}, - description = #{description} - - WHERE site_id = #{siteId} AND deleted = 0 - - diff --git a/src/main/resources/org/craftercms/studio/api/v2/dal/GroupDAO.xml b/src/main/resources/org/craftercms/studio/api/v2/dal/GroupDAO.xml index 24c96d710f..f43ad82bb6 100644 --- a/src/main/resources/org/craftercms/studio/api/v2/dal/GroupDAO.xml +++ b/src/main/resources/org/craftercms/studio/api/v2/dal/GroupDAO.xml @@ -1,6 +1,6 @@