Java tutorial
package org.opencommercesearch.remote.assetmanager.editor.service; /* * Licensed to OpenCommerceSearch under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. OpenCommerceSearch licenses this * file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.sql.Timestamp; import java.util.Collection; import java.util.HashSet; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.opencommercesearch.repository.RuleProperty; import atg.nucleus.GenericService; import atg.remote.assetmanager.editor.model.PropertyUpdate; import atg.remote.assetmanager.editor.service.AssetEditorInfo; import atg.repository.MutableRepository; import atg.repository.MutableRepositoryItem; import atg.repository.RepositoryException; import atg.repository.RepositoryItem; import atg.repository.DisplayableItem; import atg.userprofiling.Profile; public class DefaultRuleAssetValidator extends GenericService { protected static final String CATEGORY_PAGES = "Category Pages"; protected static final String SEARCH_PAGES = "Search Pages"; protected static final String ALL_PAGES = "All Pages"; protected static final String WILDCARD = "*"; protected static final String ROLES = "roles"; protected static final String ERROR_MSG = "Query can't be empty for search pages. Provide a query. * is not allowed for search pages"; protected static final String NULL_PROPERTY_ERROR_MSG = "This field can't be empty, please enter a valid value"; protected static final String INVALID_END_DATE_ERROR_MSG = "End date must be after start date"; private Set<String> superUserRoleNames = new HashSet<String>(); private Set<String> superUserRoleIds = new HashSet<String>(); /** * Called when an asset is created. Ensures that the entered fields are valid. * @param editorInfo The current editor information (such as the asset being updated) * @param updates Collection of updates for the current asset. For example, fields that now have a value. */ public void validateNewAsset(AssetEditorInfo editorInfo, Collection updates, Profile profile) { doValidation(editorInfo, updates, profile); doDateValidation(editorInfo, updates); } /** * Called when an asset is updated. Ensures that the entered fields are valid. * @param editorInfo The current editor information (such as the asset being updated) * @param updates Collection of updates for the current asset. For example, fields that now have a value. */ public void validateUpdateAsset(AssetEditorInfo editorInfo, Collection updates, Profile profile) { doValidation(editorInfo, updates, profile); doDateValidation(editorInfo, updates); } /** * Performs the actual validation. * <p/> * Subclasses should override this method if more specific validation is required. * @param editorInfo The current editor information (such as the asset being updated) * @param updates Collection of updates for the current asset. For example, fields that now have a value. */ public void doValidation(AssetEditorInfo editorInfo, Collection updates, Profile profile) { PropertyUpdate targetProperty = BaseAssetService.findPropertyUpdate(RuleProperty.TARGET, updates); PropertyUpdate queryProperty = BaseAssetService.findPropertyUpdate(RuleProperty.QUERY, updates); if ((targetProperty != null || queryProperty != null) && !this.skipSearchPagesValidation(editorInfo, updates, profile)) { validateTargetAndQueryUpdate(editorInfo, targetProperty, queryProperty); } } /** * Performs common rule date validation. * <p/> * All rules must have an end and start date. This method ensures that both dates are valid. * @param editorInfo The current editor information (such as the asset being updated) * @param updates Collection of updates for the current asset. For example, fields that now have a value. */ public void doDateValidation(AssetEditorInfo editorInfo, Collection updates) { //Validate start and end dates. You shouldn't be able to specify an end date before the given start date. PropertyUpdate startDateProperty = BaseAssetService.findPropertyUpdate(RuleProperty.START_DATE, updates); PropertyUpdate endDateProperty = BaseAssetService.findPropertyUpdate(RuleProperty.END_DATE, updates); validateStartAndEndDateUpdate(editorInfo, startDateProperty, endDateProperty); } /** * Validate that if we select a target = searchPages, then the query parameter should be populated * If we selected allPages or categoryPages, then the query will be default to * if the user didn't provided another value */ protected void validateTargetAndQueryUpdate(AssetEditorInfo editorInfo, PropertyUpdate targetProperty, PropertyUpdate queryProperty) { String targetValue = null; String queryValue = null; if (targetProperty != null) { targetValue = (String) targetProperty.getPropertyValue(); } if (StringUtils.isBlank(targetValue)) { targetValue = getPersistedTarget(editorInfo); } if (isLoggingInfo()) { logInfo("processing target: " + targetValue); } if (ALL_PAGES.equals(targetValue)) { setDefaultQuery(editorInfo, queryProperty); } else if (SEARCH_PAGES.equals(targetValue)) { if (queryProperty != null) { //scenario where we are providing a new query term or we are changing it queryValue = (String) queryProperty.getPropertyValue(); if (StringUtils.isBlank(queryValue) || WILDCARD.equals(queryValue)) { editorInfo.getAssetService().addError(queryProperty.getPropertyName(), ERROR_MSG); } } else { //scenario where we are updating this asset but the query term wasn't changed queryValue = getPersistedQuery(editorInfo); if (StringUtils.isBlank(queryValue) || WILDCARD.equals(queryValue)) { if (isLoggingInfo()) { logInfo("adding error cause asset doesn't have query set for search pages scenario"); } editorInfo.getAssetService().addError(RuleProperty.QUERY, ERROR_MSG); } } } else if (CATEGORY_PAGES.equals(targetValue)) { setDefaultQuery(editorInfo, queryProperty); } } /** * Checks that the start and end date are properly specified. * <p/> * A common error would be to enter an end date which is before the given start date. */ protected void validateStartAndEndDateUpdate(AssetEditorInfo editorInfo, PropertyUpdate startDateProperty, PropertyUpdate endDateProperty) { Timestamp startDate = null; Timestamp endDate = null; if (startDateProperty == null) { //This field wasn't updated, so fetch the value from the asset. RepositoryItem currentItem = (RepositoryItem) editorInfo.getAssetWrapper().getAsset(); startDate = (Timestamp) currentItem.getPropertyValue(RuleProperty.START_DATE); } else { String startDateValue = (String) startDateProperty.getPropertyValue(); if (startDateValue != null && !startDateValue.isEmpty()) { startDate = Timestamp.valueOf(startDateValue); //Timestamp.valueOf understands ISO 8601 date format. } } if (endDateProperty == null) { //This field wasn't updated, so fetch the value from the asset. RepositoryItem currentItem = (RepositoryItem) editorInfo.getAssetWrapper().getAsset(); endDate = (Timestamp) currentItem.getPropertyValue(RuleProperty.END_DATE); } else { String endDateValue = (String) endDateProperty.getPropertyValue(); if (endDateValue == null || endDateValue.isEmpty()) { editorInfo.getAssetService().addError(RuleProperty.END_DATE, NULL_PROPERTY_ERROR_MSG); return; //Don't do more validation. } else { endDate = Timestamp.valueOf(endDateValue); //Timestamp.valueOf understands ISO 8601 date format. } } if (startDate != null && endDate.before(startDate)) { editorInfo.getAssetService().addError(RuleProperty.END_DATE, INVALID_END_DATE_ERROR_MSG); } } protected boolean hasQuery(RepositoryItem currentItem) { String query = (String) currentItem.getPropertyValue(RuleProperty.QUERY); return StringUtils.isNotBlank(query); } protected String getPersistedTarget(AssetEditorInfo editorInfo) { RepositoryItem currentItem = (RepositoryItem) editorInfo.getAssetWrapper().getAsset(); return (String) currentItem.getPropertyValue(RuleProperty.TARGET); } protected String getPersistedQuery(AssetEditorInfo editorInfo) { RepositoryItem currentItem = (RepositoryItem) editorInfo.getAssetWrapper().getAsset(); return (String) currentItem.getPropertyValue(RuleProperty.QUERY); } protected void setDefaultQuery(AssetEditorInfo editorInfo, PropertyUpdate queryProperty) { RepositoryItem currentItem = (RepositoryItem) editorInfo.getAssetWrapper().getAsset(); //only set a default query if it didn't had already a query value or if this update //didn't change the query value if (!hasQuery(currentItem) && queryProperty == null) { try { MutableRepository rep = (MutableRepository) currentItem.getRepository(); MutableRepositoryItem mutableItem = rep.getItemForUpdate(currentItem.getRepositoryId(), currentItem.getItemDescriptor().getItemDescriptorName()); mutableItem.setPropertyValue(RuleProperty.QUERY, "*"); rep.updateItem(mutableItem); } catch (RepositoryException e) { editorInfo.getAssetService() .addError("error adding default query to rule:" + currentItem.getRepositoryId()); if (isLoggingWarning()) { logWarning("error adding default query to rule:" + currentItem.getRepositoryId()); } } } else { if (isLoggingDebug()) { logDebug("category or all pages target had a specific query. Keeping it"); } } } protected boolean skipSearchPagesValidation(AssetEditorInfo editorInfo, Collection updates, Profile profile) { if (profile != null) { Object roles = profile.getPropertyValue(ROLES); if (roles instanceof Set<?>) { for (Object objRole : (Set<?>) roles) { String roleId = objRole instanceof RepositoryItem ? ((RepositoryItem) objRole).getRepositoryId() : ""; String roleName = objRole instanceof DisplayableItem ? ((DisplayableItem) objRole).getItemDisplayName() : ""; if (this.superUserRoleNames.contains(roleName) || this.superUserRoleIds.contains(roleId)) { if (isLoggingWarning()) { logWarning("This user is allowed to skip Search Pages validation because has " + roleName + "/" + roleId + " role."); } return true; } } } } return false; } public String[] getSuperUserRoleNames() { return this.superUserRoleNames.toArray(new String[this.superUserRoleNames.size()]); } public void setSuperUserRoleNames(String[] superUserRoleNames) { this.superUserRoleNames.clear(); if (superUserRoleNames != null) { for (String role : superUserRoleNames) { this.superUserRoleNames.add(role); } } } public String[] getSuperUserRoleIds() { return this.superUserRoleIds.toArray(new String[this.superUserRoleIds.size()]); } public void setSuperUserRoleIds(String[] superUserRoleIds) { this.superUserRoleIds.clear(); if (superUserRoleIds != null) { for (String role : superUserRoleIds) { this.superUserRoleIds.add(role); } } } }