/* bcwti
*
* Copyright (c) 2008 Parametric Technology Corporation (PTC). All Rights Reserved.
*
* This software is the confidential and proprietary information of PTC
* and is subject to the terms of a software license agreement. You shall
* not disclose such confidential information and shall use it only in accordance
* with the terms of the license agreement.
*
* ecwti
*/
package com.ptc.windchill.enterprise.wip;
import java.beans.PropertyVetoException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import org.apache.log4j.Logger;
import wt.access.AccessControlHelper;
import wt.access.AccessPermission;
import wt.content.ContentHelper;
import wt.content.ContentItem;
import wt.content.ExternalStoredData;
import wt.content.FormatContentHolder;
import wt.content.URLData;
import wt.fc.ReferenceFactory;
import wt.fc.WTReference;
import wt.folder.CabinetBased;
import wt.folder.Folder;
import wt.folder.FolderEntry;
import wt.folder.FolderHelper;
import wt.inf.container.WTContained;
import wt.inf.container.WTContainerHelper;
import wt.inf.container.WTContainerRef;
import wt.log4j.LogR;
import wt.org.WTPrincipal;
import wt.org.WTUser;
import wt.preference.PreferenceClient;
import wt.preference.PreferenceHelper;
import wt.sandbox.SandboxHelper;
import wt.session.SessionHelper;
import wt.util.WTContext;
import wt.util.WTException;
import wt.util.WTInvalidParameterException;
import wt.vc.Iterated;
import wt.vc.VersionControlHelper;
import wt.vc.wip.WorkInProgressHelper;
import wt.vc.wip.Workable;
import com.ptc.core.ui.resources.FeedbackType;
import com.ptc.core.ui.validation.DefaultUIComponentValidator;
import com.ptc.core.ui.validation.UIComponentValidator;
import com.ptc.core.ui.validation.UIValidationCriteria;
import com.ptc.core.ui.validation.UIValidationFeedbackMsg;
import com.ptc.core.ui.validation.UIValidationKey;
import com.ptc.core.ui.validation.UIValidationResult;
import com.ptc.core.ui.validation.UIValidationResultSet;
import com.ptc.core.ui.validation.UIValidationStatus;
public class DefaultWIPValidator extends DefaultUIComponentValidator {
private Logger logger = LogR.getLogger(DefaultWIPValidator.class.getName());
private ReferenceFactory refFactory = null;
private static final String WIP_VALIDATION_RESOURCE = "com.ptc.windchill.enterprise.wip.WIPResource";
public static final String FULL = "full";
public static final String LIMITED = "limited";
public static final String SELECTED = "selected";
public static final String FORMSUBMISSION = "formSubmission";
protected final static String CHECKOUT_AND_EDIT = "checkoutAndEdit";
protected final static String CHECKIN = "checkin";
protected final static String CHECKOUT = "checkout";
protected final static String CHECKOUT_AND_DOWNLOAD = "checkout_and_download";
protected final static String EDIT = "edit";
protected final static String REPLACE_CONTENT = "replace_content";
protected final static String UNDOCHECKOUT = "undocheckout";
protected enum accessPermissions {
MODIFY, MODIFY_CONTENT, DOWNLOAD;
// Do arithmetic op represented by this constant
AccessPermission getAccessPermission() {
switch (this) {
case MODIFY:
return AccessPermission.MODIFY;
case MODIFY_CONTENT:
return AccessPermission.MODIFY_CONTENT;
case DOWNLOAD:
return AccessPermission.DOWNLOAD;
}
throw new AssertionError("Unknown accessPermission: " + this);
}
}
protected class wipValidationResult {
private boolean success = false;
private List messages = null;
private boolean hide = false;
private boolean confirm = false;
public void setConfirm(boolean confirm) {
this.confirm = confirm;
}
public boolean isConfirm() {
return confirm;
}
public List getMessage() {
return messages;
}
public boolean isHide() {
return hide;
}
public boolean isSuccess() {
return success;
}
public void addMessage(UIValidationFeedbackMsg msg) {
if (messages == null) {
messages = new ArrayList();
}
messages.add(msg);
}
public wipValidationResult(boolean success) {
this.success = success;
}
public wipValidationResult(boolean success, boolean hide) {
this.success = success;
this.hide = hide;
}
public UIValidationResult getValidationResult(
UIValidationKey validation_key, WTReference wt_ref,
String validation_type) {
UIValidationStatus status;
if (confirm) {
status = UIValidationStatus.PROMPT_FOR_CONFIRMATION;
}
else if (success) {
if (validation_type.equals(FULL)) {
status = UIValidationStatus.ENABLED;
} else {
status = UIValidationStatus.PERMITTED;
}
} else {
if (validation_type.equals(FULL)) {
if (hide) {
status = UIValidationStatus.HIDDEN;
} else {
status = UIValidationStatus.DISABLED;
}
} else {
status = UIValidationStatus.DENIED;
}
}
return new UIValidationResult(validation_key, status, wt_ref,
messages);
}
}
/**
* This implementation of performLimitedPreValdiation will check get
* checkout state of all the Workable objects in the validation_criteria's
* targetObjects WTCollection, and base its validation results on whether an
* object in the given state can have the specified action performed on it.
* (e.g., an object in the checked-in state can not have an undo checkout
* action performed on it)
*
* At a minimum, a caller of this method should provide the targetObjects
* WTCollection in the validation_criteria argument.
*
* The expected validation_key arguments for this method are: checkin
* checkout undocheckout checkout_and_edit edit replace_content
*
*
*
* Supported API: false
*
* @param validation_key
* The String identifying the action or component being
* validated.
* @param validation_criteria
* Object holding information required to perform validation
* tasks.
* @param locale
* The user's Locale. If a null value is passed in, the
* session locale will be used.
* @return UIValidationResultSet
*/
@Override
public UIValidationResultSet performLimitedPreValidation(
UIValidationKey validation_key,
UIValidationCriteria validation_criteria, Locale locale) {
UIValidationResultSet result_set = null;
logger
.debug("ENTERING DefaultWIPValidator.performLimitedPreValidation");
logger.trace(" validtionKey -> " + validation_key);
logger.trace(" validation_criteria -> "
+ validation_criteria.toString());
try {
result_set = performWIPValidation(validation_key,
validation_criteria, locale, LIMITED, validation_key
.getComponentID().toString());
} catch (WTException e) {
e.printStackTrace();
}
logger.trace("RETURNING " + result_set.toString());
logger.debug("EXITING DefaultWIPValidator.performLimitedPreValidation");
return result_set;
}
/**
* performFullPreValidation is called whenever a validation of an action is
* called for before it is displayed to the user. This method will be called
* everytime the user clicks on the top level Actions Menu in details page
* or row level one in Folders and Home page. The method will return a
* resultset with resultset set to be DISABLED or ENABLED.
*
* @param validation_key
* The String identifying the action or component being
* validated.
* @param validation_criteria
* Object holding information required to perform validation
* tasks.
* @param locale
* The user's Locale. If a null value is passed in, the
* session locale will be used.
* @return UIValidationResultSet
*/
@Override
public UIValidationResultSet performFullPreValidation(
UIValidationKey validation_key,
UIValidationCriteria validation_criteria, Locale locale) {
UIValidationResultSet result_set = null;
logger
.debug("ENTERING DefaultWIPValidator.performFullPreValidation zzz");
logger.trace(" validtionKey -> " + validation_key);
logger.trace(" validation_criteria -> "
+ validation_criteria.toString());
try {
// Checks for Work Package related validation
UIComponentValidator wpValidator = getSubValidator("WPValidation");
if (wpValidator != null) {
result_set = wpValidator.performFullPreValidation(
validation_key, validation_criteria, locale);
if (!result_set.getAllResults().isEmpty()) {
return result_set;
}
}// Work package related validation ends
result_set = performWIPValidation(validation_key,
validation_criteria, locale, FULL, validation_key
.getComponentID().toString());
} catch (WTException e) {
e.printStackTrace();
}
logger.trace("RETURNING " + result_set.toString());
logger.debug("EXITING DefaultWIPValidator.performFullPreValidation");
return result_set;
}
/**
* validateSelectedAction is called whenever a validation of an action is
* called for after it is clicked by the user. This method will be called
* everytime the user clicks the action popped up on the top level Actions
* Menu in details page or row level one in Folders and Home page. The
* method will return a PERMITTED/DENIED status in the resultset.
*
* @param validation_key
* The String identifying the action or component being
* validated.
* @param validation_criteria
* Object holding information required to perform validation
* tasks.
* @param locale
* The user's Locale. If a null value is passed in, the
* session locale will be used.
* @return UIValidationResult
*/
@Override
public UIValidationResult validateSelectedAction(
UIValidationKey validation_key,
UIValidationCriteria validation_criteria, Locale locale) {
logger.debug("ENTERING DefaultWIPValidator.validateSelectedAction");
logger.trace(" validtionKey -> " + validation_key);
logger.trace(" validation_criteria -> "
+ validation_criteria.toString());
UIValidationResultSet result_set = null;
try {
result_set = performWIPValidation(validation_key,
validation_criteria, locale, SELECTED, validation_key
.getComponentID().toString());
} catch (WTException e) {
e.printStackTrace();
}
logger.trace("RETURNING " + result_set.toString());
logger.debug("EXITING DefaultWIPValidator.performFullPreValidation");
UIValidationResult result = result_set.getAllResults().get(0);
logger.trace("RETURNING " + result.toString());
logger.debug("EXITING DefaultWIPValidator.validateSelectedAction");
return result;
}
@Override
public UIValidationResultSet validateSelectedMultiSelectAction(
UIValidationKey validation_key,
UIValidationCriteria validation_criteria, Locale locale) {
UIValidationResultSet result_set = null;
logger
.debug("ENTERING DefaultWIPValidator.validateSelectedMultiSelectAction");
logger.trace(" validtionKey -> " + validation_key);
logger.trace(" validation_criteria -> "
+ validation_criteria.toString());
try {
result_set = performWIPValidation(validation_key,
validation_criteria, locale, SELECTED, validation_key
.getComponentID().toString());
} catch (WTException e) {
e.printStackTrace();
}
logger.trace("RETURNING " + result_set.toString());
logger
.debug("EXITING DefaultWIPValidator.validateSelectedMultiSelectAction");
return result_set;
}
/**
* performWIPValidation method will check for the specific action called
* upon and then decide which of the particular validator needs to be
* called.
*
* @param validation_key
* The String identifying the action or component being
* validated.
* @param validation_criteria
* Object holding information required to perform validation
* tasks.
* @param locale
* The user's Locale. If a null value is passed in, the
* session locale will be used.
* @param validation_type
* Validation type. This is Full or Selected.
* @return UIValidationResult
*/
protected UIValidationResultSet performWIPValidation(
UIValidationKey validation_key,
UIValidationCriteria validation_criteria, Locale locale,
String validation_type, String validationAction) throws WTException {
UIValidationResultSet result_set = new UIValidationResultSet();
WTReference wr = validation_criteria.getContextObject();
WTUser user = (WTUser) validation_criteria.getUser().getPrincipal();
if (user == null) {
user = (WTUser) SessionHelper.manager.getPrincipal();
}
Workable workable = null;
if (Workable.class.isAssignableFrom(wr.getReferencedClass())) {
workable = (Workable) wr.getObject();
}
if (user == null) {
throw new WTInvalidParameterException(
"No user passed into the DefaultWIPValidator");
}
if (workable == null) {
throw new WTInvalidParameterException(
"No workable passed into the DefaultWIPValidator");
}
if (validationAction == null) {
throw new WTInvalidParameterException(
"No action passed into the DefaultWIPValidator");
}
logger.debug("user:" + user.toString());
logger.debug("workable:" + workable.toString());
logger.debug("action:" + validationAction.toString());
if (validationAction.equals(CHECKIN)) {
logger.debug("CHECKIN validation");
wipValidationResult result = performCheckinValidation(
validation_key, workable, validation_criteria,
validation_type, user);
logger.debug("CHECKIN validation type:" + validation_type
+ " enabled:" + result.isSuccess());
result_set.addResult(result.getValidationResult(validation_key, wr,
validation_type));
} else if (validationAction.equals(CHECKOUT)) {
logger.debug("CHECKOUT validation");
wipValidationResult result = performCheckoutValidation(
validation_key, workable, validation_criteria,
validation_type, user);
logger.debug("CHECKOUT validation type:" + validation_type
+ " enabled:" + result.isSuccess());
result_set.addResult(result.getValidationResult(validation_key, wr,
validation_type));
} else if (validationAction.equals(CHECKOUT_AND_EDIT)) {
logger.debug("CHECKOUT_AND_EDIT validation");
wipValidationResult result = performCheckoutAndEditValidation(
validation_key, workable, validation_criteria,
validation_type, user);
logger.debug("CHECKOUT_AND_EDIT validation type:" + validation_type
+ " enabled:" + result.isSuccess());
result_set.addResult(result.getValidationResult(validation_key, wr,
validation_type));
} else if (validationAction.equals(EDIT)) {
logger.debug("EDIT validation");
wipValidationResult result = performEditValidation(workable, user);
logger.debug("EDIT validation type:" + validation_type
+ " enabled:" + result.isSuccess());
result_set.addResult(result.getValidationResult(validation_key, wr,
validation_type));
} else if (validationAction.equals(UNDOCHECKOUT)) {
logger.debug("UNDOCHECKOUT validation");
wipValidationResult result = performUndoCheckoutValidation(
validation_key, workable, validation_criteria,
validation_type, user);
logger.debug("UNDOCHECKOUT validation type:" + validation_type
+ " enabled:" + result.isSuccess());
result_set.addResult(result.getValidationResult(validation_key, wr,
validation_type));
} else if (validationAction.equals(REPLACE_CONTENT)) {
logger.debug("REPLACE_CONTENT validation");
wipValidationResult result = performReplaceContentValidation(
validation_key, workable, validation_criteria,
validation_type, user);
logger.debug("REPLACE_CONTENT validation type:" + validation_type
+ " enabled:" + result.isSuccess());
result_set.addResult(result.getValidationResult(validation_key, wr,
validation_type));
} else if (validationAction.equals(CHECKOUT_AND_DOWNLOAD)) {
logger.debug("CHECKOUT_AND_DOWNLOAD validation");
wipValidationResult result = performCheckoutAndDownloadValidation(
validation_key, workable, validation_criteria,
validation_type, user);
logger.debug("CHECKOUT_AND_DOWNLOAD validation type:"
+ validation_type + " enabled:" + result.isSuccess());
result_set.addResult(result.getValidationResult(validation_key, wr,
validation_type));
}
return result_set;
}
/**
*
* performEditValidation method will called upon doing the Edit action
* validation. This validator logic allows or enables the action on the
* workables for a user which satisifes the following conditions.
* - The user has MODIFY permission set for this workable. - The workable
* is checked out. - and checked-out to the current user.
*
* @param validation_key
* The String identifying the action or component being
* validated.
* @param workable
* Object on which the action is going to operate.
* @param validation_criteria
* Object holding information required to perform validation
* tasks.
* @param validation_type
* Validation type. This is Full or Selected.
*
* @return UIValidationResult
*/
protected wipValidationResult performEditValidation(Workable workable,
WTPrincipal userP) throws WTException {
boolean modifyAccess = hasAccess(userP, workable,
accessPermissions.MODIFY);
logger.debug("modifyAccess:" + modifyAccess);
if (!modifyAccess)
return new wipValidationResult(false, true);
/*
* If Edit is allowed on Checkin Objects then check that the object is
* not checked out by anyone else.
*/
boolean checkedOutToUser = isCheckedOutToUser(workable, userP);
logger.debug("checkedOutToUser:" + checkedOutToUser);
if (checkedOutToUser)
return new wipValidationResult(true);
return new wipValidationResult(false);
}
/**
* performCheckoutAndEditValidation method will called upon doing the
* CheckoutAndEdit action validation. This validator logic allows or enables
* the action on the workables for a particular user which is satisifes the
* following conditions. - The preference EDIT_ACTION_ON_CHECKED_IN is set. -
* The user and workable passes the Checkout validation.
*
* @param validation_key
* The String identifying the action or component being
* validated.
* @param workable
* Object on which the action is going to operate.
* @param validation_criteria
* Object holding information required to perform validation
* tasks.
* @param validation_type
* Validation type. This is Full or Selected.
*
*
* @return UIValidationResult
*/
protected wipValidationResult performCheckoutAndEditValidation(
UIValidationKey validation_key, Workable workable,
UIValidationCriteria validation_criteria, String validation_type,
WTUser user) throws WTException {
/**
* Display of the CO and Edit action is controlled by the preference
* EDIT_ACTION_ON_CHECKED_IN. If this is true means show the Checkout
* And Edit action on checked in objects. This is the only way an CO and
* Edit validation will differ from CO.
*/
boolean allowEditOnCheckin = (Boolean) getPreferenceService().getValue(
validation_criteria.getParentContainer(),
"EDIT_ACTION_ON_CHECKED_IN",
PreferenceClient.WINDCHILL_CLIENT_NAME,
user);
logger.debug("allowEditOnCheckin:" + allowEditOnCheckin);
if (!allowEditOnCheckin) {
return new wipValidationResult(false, true);
}
/**
* Now check for the checkout validation.
*/
return performCheckoutValidation(validation_key, workable,
validation_criteria, validation_type, user);
}
/**
* performUndoCheckoutValidation method will called upon doing the
* UndoCheckout action validation. This validator logic allows or enables
* the action on the workables for a particular user which is checked-out by
* that user or if the user is administrator. It will also not be displayed
* if the workable is PDMChecked out.
*
* @param validation_key
* The String identifying the action or component being
* validated.
* @param validation_criteria
* Object holding information required to perform validation
* tasks.
* @param validation_type
* Validation type. This is Full or Selected.
*
* @return UIValidationResult
*/
protected wipValidationResult performUndoCheckoutValidation(
UIValidationKey validation_key, Workable workable,
UIValidationCriteria validation_criteria, String validation_type,
WTUser user) throws WTException {
if (workable == null)
return new wipValidationResult(false);
// WTUser user = (WTUser)validation_criteria.getUser().getPrincipal();
/*
* Check if the object is locked by the sandbox checkout. Locked object
* does not have the permission for UndoCheckout.
*/
boolean chkoutToSand = isCheckedOutToSandbox(workable);
logger.debug("chkoutToSand:" + chkoutToSand);
if (chkoutToSand)
return new wipValidationResult(false);
boolean checkedOut = isCheckedOut(workable);
logger.debug("checkedOut:" + checkedOut);
if (!checkedOut) {
return new wipValidationResult(false);
}
/*
* If the working copy is not checked out to current user or the current
* user is not the administrator of its container then disable it. I use
* an if else here so that I can both print debugging information, but
* also so that I can prevent the server hit to determine if the user is
* an administrator if possible.
*/
boolean checkedOutToUser = isCheckedOutToUser(workable, user);
logger.debug("checkedOutToUser:" + checkedOutToUser);
if (checkedOutToUser) {
return new wipValidationResult(true);
} else {
boolean userIsAdmin = getWTContainerService().isAdministrator(
validation_criteria.getParentContainer(), user);
logger.debug("userIsAdmin:" + userIsAdmin);
if (userIsAdmin) {
return new wipValidationResult(true);
}
}
/* If the object is a working copy & ADMINISTRATIVE permission is lacking,
* then allow undo-checkout only if DELETE and MODIFY is allowed
* else
* If the object is original copy and has ADMINISTRATIVE permissions, only then undo-checkout is allowed.
*/
if (WorkInProgressHelper.isWorkingCopy(workable))
{
if ((AccessControlHelper.manager.hasAccess(workable, AccessPermission.ADMINISTRATIVE)))
return new wipValidationResult(true);
else
{
Folder workingFolder = FolderHelper.getFolder((FolderEntry)workable);
boolean userHasDeleteOnWorking = AccessControlHelper.manager.hasAccess(workable, AccessPermission.DELETE);
boolean userHasModifyOnFolder = (workingFolder == null) ? true : AccessControlHelper.manager.hasAccess(workingFolder, AccessPermission.MODIFY);
if (userHasDeleteOnWorking && userHasModifyOnFolder)
return new wipValidationResult(true);
}
}
else
if (WorkInProgressHelper.isCheckedOut(workable))
{
if (AccessControlHelper.manager.hasAccess(workable, AccessPermission.ADMINISTRATIVE))
return new wipValidationResult(true);
}
return new wipValidationResult(false);
}
/**
* performCheckinValidation method will called upon doing the Checkin action
* validation. This validator logic allows or enables the action on the
* workables for a particular user which is satisifes the following
* conditions. - The workable is checked out and to the current user. - The
* workable is not PDMChecked out.
*
* @param validation_key
* The String identifying the action or component being
* validated.
* @param validation_criteria
* Object holding information required to perform validation
* tasks.
* @param validation_type
* Validation type. This is Full or Selected.
* @param wtuser
* temporary parameter until the deprecated public peer of this
* method is removed
*
* @return UIValidationResult
*/
protected wipValidationResult performCheckinValidation(
UIValidationKey validation_key, Workable workable,
UIValidationCriteria validation_criteria, String validation_type,
WTUser user) throws WTException {
if (workable == null)
return new wipValidationResult(false);
if (user == null)
user = (WTUser) validation_criteria.getUser().getPrincipal();
boolean checkedOutToSandbox = isCheckedOutToSandbox(workable);
logger.debug("checkedOutToSandbox:" + checkedOutToSandbox);
if (checkedOutToSandbox) {
return new wipValidationResult(false);
}
if (validation_type.equals(LIMITED)) {
logger.debug("doing limited validation");
boolean checkedOut = isCheckedOut(workable);
logger.debug("checkedOut:" + checkedOut);
if (checkedOut == false) {
return new wipValidationResult(false);
}
return new wipValidationResult(true);
}
else if (validation_type.equals(FULL)
|| validation_type.equals(SELECTED)
|| validation_type.equals(FORMSUBMISSION)) {
if (workable instanceof CabinetBased) {
CabinetBased orig;
if (WorkInProgressHelper.isWorkingCopy(workable)) {
orig = (CabinetBased) WorkInProgressHelper.service
.originalCopyOf(workable);
} else {
orig = (CabinetBased) workable;
}
}
boolean checkedOutToUser = isCheckedOutToUser(workable, user);
logger.debug("checkedOutToUser:" + checkedOutToUser);
if (!checkedOutToUser)
return new wipValidationResult(false);
return new wipValidationResult(true);
}
// If the validation is not of Full/Selected or Limited just disable the
// action
return new wipValidationResult(false);
}
/**
*
* performCheckoutValidation method will called upon doing the Checkout
* action validation. This validator logic allows or enables the action on
* the workables for a particular user which is satisifes the following
* conditions. - The workable is checked-in. - The user has MODIFY access. (
* As of now the validation does not check for the access against the role
* but just the user.) - The workable is the latest copy or if not the
* preference for non-latest iteration checkout is set. - The workable is
* not PDMChecked out.
*
* @param validation_key
* The String identifying the action or component being
* validated.
* @param workable
* Object on which the action is going to operate.
* @param validation_criteria
* Object holding information required to perform validation
* tasks.
* @param validation_type
* Validation type. This is Full or Selected.
* @param wtuser
* temporary parameter until the deprecated public peer of this
* method is removed
*
* @return UIValidationResult
*/
protected wipValidationResult performCheckoutValidation(
UIValidationKey validation_key, Workable workable,
UIValidationCriteria validation_criteria, String validation_type,
WTUser user) throws WTException {
String feedbackMessage = "";
ResourceBundle wipValidationRb = ResourceBundle.getBundle(
WIP_VALIDATION_RESOURCE, WTContext.getContext().getLocale());
if (workable == null)
return new wipValidationResult(false);
if (user == null)
user = (WTUser) validation_criteria.getUser().getPrincipal();
if (validation_type.equals(LIMITED)) {
boolean checkedOut = isCheckedOut(workable);
logger.debug("isCheckedOut:" + checkedOut);
return new wipValidationResult(!checkedOut);
} else if (validation_type.equals(FULL)
|| validation_type.equals(SELECTED)
|| validation_type.equals(FORMSUBMISSION)) {
/*
* Check if the object is locked by the sandbox checkout. Locked
* object does not have the permission for Checkout.
*/
boolean checkedOutToSandbox = SandboxHelper
.isCheckedOutToSandbox(workable);
logger.debug("checkedOutToSandbox:" + checkedOutToSandbox);
if (checkedOutToSandbox) {
return new wipValidationResult(false);
}
boolean checkoutAllowed = isCheckoutAllowed(workable);
logger.debug("checkoutAllowed:" + checkoutAllowed);
if (!checkoutAllowed)
return new wipValidationResult(false);
// Check the access permisson against the user.
boolean modifyAccess = hasAccess(user, workable,
accessPermissions.MODIFY);
logger.debug("modifyAccess:" + modifyAccess);
if (!modifyAccess) {
feedbackMessage = wipValidationRb
.getString(WIPResource.CHECKOUT_WITHOUT_ACCESS);
UIValidationFeedbackMsg message = new UIValidationFeedbackMsg(
feedbackMessage, (FeedbackType.ERROR));
wipValidationResult result = new wipValidationResult(false, true);
result.addMessage(message);
return result;
}
boolean checkedOut = isCheckedOut(workable);
logger.debug("checkedOut:" + checkedOut);
if (checkedOut) {
feedbackMessage = wipValidationRb
.getString(WIPResource.ALREADY_CHECKEDOUT);
UIValidationFeedbackMsg message = new UIValidationFeedbackMsg(
feedbackMessage, (FeedbackType.ERROR));
wipValidationResult result = new wipValidationResult(false);
result.addMessage(message);
return result;
}
/*
* Check if its the latest iteration along with its preferance. If
* not then allow checkout with a warning message.
*/
boolean latestIteration = isLatestIteration((Iterated) workable);
logger.debug("latestIteration:" + latestIteration);
if (!latestIteration) {
boolean allowNonLatestIterationCheckout = true;
if (user instanceof WTUser) {
WTContainerRef containerRef = null;
if (validation_criteria != null)
containerRef = validation_criteria.getParentContainer();
if (containerRef == null && workable instanceof WTContained)
containerRef = ((WTContained) workable).getContainerReference();
logger.debug("containerRef : " + containerRef);
Object prefValue = getPreferenceService().getValue(
containerRef,
"/wt/vc/wip/DefaultType/wt.vc.wip.NonLatestCheckoutValidator",
PreferenceClient.WINDCHILL_CLIENT_NAME,
user);
if(prefValue!=null){
logger.debug("prefValue: " + prefValue.toString());
// If the user doesn't rerun the preference load after migrating to X12, this preference
// will still be a boolean, hence this Boolean/String check is included here.
// This could probably be removed at/after X20.
if(prefValue instanceof Boolean)
allowNonLatestIterationCheckout=(Boolean)prefValue;
if(prefValue instanceof String){
if(prefValue.equals("false"))
allowNonLatestIterationCheckout=false;
}
}
else
allowNonLatestIterationCheckout=false;
logger.debug("allowNonLatestIterationCheckout:"
+ allowNonLatestIterationCheckout);
}
if (allowNonLatestIterationCheckout) {
if (validation_type.equals(FORMSUBMISSION)) {
wipValidationResult result = new wipValidationResult(true);
result.setConfirm(true);
feedbackMessage = wipValidationRb
.getString(WIPResource.NON_LATEST_ITERATION);
UIValidationFeedbackMsg message = new UIValidationFeedbackMsg(
feedbackMessage, (FeedbackType.CONFIRMATION));
result.addMessage(message);
return result;
} else {
return new wipValidationResult(true);
}
}
else {
return new wipValidationResult(false);
}
}
return new wipValidationResult(true);
}
return new wipValidationResult(false);
}
/**
*
* performReplaceContentValidation method will called upon doing the
* ReplaceContent action validation. This validator logic allows or enables
* the action on the workables for a particular user which satisifes the
* following conditions. - The user had MODIFY_CONTENT permission set for
* this workable. - The user and workable passes the Checkout validation.
*
* @param validation_key
* The String identifying the action or component being
* validated.
* @param workable
* Object on which the action is going to operate.
* @param validation_criteria
* Object holding information required to perform validation
* tasks.
* @param validation_type
* Validation type. This is Full or Selected.
* @param wtuser
* temporary parameter until the deprecated public peer of this
* method is removed
*
* @return UIValidationResult
*/
protected wipValidationResult performReplaceContentValidation(
UIValidationKey validation_key, Workable workable,
UIValidationCriteria validation_criteria, String validation_type,
WTUser user) throws WTException {
if (user == null)
user = (WTUser) validation_criteria.getUser().getPrincipal();
if (wt.content.FormatContentHolder.class.isAssignableFrom(workable
.getClass())) {
Boolean prefRC = (Boolean) getPreferenceService().getValue(
validation_criteria.getParentContainer(),
"REPLACE_CONTENT_OFFERED",
PreferenceClient.WINDCHILL_CLIENT_NAME,
user);
if (prefRC.booleanValue()) {
/***************************************************************
* MODIFY_CONTENT access permissions be checked for replace
* content instead of MODIFY permission hence cannot use the
* Edit valiation.
*/
boolean modifycontentaccess = hasAccess(user, workable,
accessPermissions.MODIFY_CONTENT);
if (modifycontentaccess) {
return performCheckoutValidation(validation_key, workable,
validation_criteria, validation_type, user);
}
else {
return new wipValidationResult(false, true);
}
} else {
return new wipValidationResult(false, true);
}
}
return new wipValidationResult(false);
}
/**
*
* performCheckoutAndDownloadValidation method will called upon doing the
* Checkout And Download action validation. This validator logic allows or
* enables the action on the workables for a particular user which satisifes
* the following conditions.
* - The user has DOWNLOAD permission set for this workable. - The user and
* workable passes the Checkout validation. - The workable has a primary
* content to download.
*
* @param validation_key
* The String identifying the action or component being
* validated.
* @param workable
* Object on which the action is going to operate.
* @param validation_criteria
* Object holding information required to perform validation
* tasks.
* @param validation_type
* Validation type. This is Full or Selected.
* @param user
* temporary parameter until the deprecated public peer of this
* method is removed
*
* @return UIValidationResult
*/
protected wipValidationResult performCheckoutAndDownloadValidation(
UIValidationKey validation_key, Workable workable,
UIValidationCriteria validation_criteria, String validation_type,
WTUser user) throws WTException {
ResourceBundle wipValidationRb = ResourceBundle.getBundle(
WIP_VALIDATION_RESOURCE, WTContext.getContext().getLocale());
if (user == null)
user = (WTUser) validation_criteria.getUser().getPrincipal();
if (wt.content.FormatContentHolder.class.isAssignableFrom(workable
.getClass())) {
// Perform limited validation
if (validation_type.equals(LIMITED)) {
boolean checkedOut = isCheckedOut(workable);
logger.debug("checkedOut:");
if (checkedOut)
return new wipValidationResult(false);
else
return new wipValidationResult(true);
} // Perform full validation
else if (validation_type.equals(FULL)
|| validation_type.equals(SELECTED)
|| validation_type.equals(FORMSUBMISSION)) {
// Check for the Download permission
// for the user in validation criteria.
boolean downloadaccess = hasAccess(user, workable,
accessPermissions.DOWNLOAD);
logger.debug("downloadaccess:" + downloadaccess);
if (downloadaccess == false) {
String feedback_message = wipValidationRb
.getString(WIPResource.CHECKOUT_WITHOUT_ACCESS);
UIValidationFeedbackMsg message = new UIValidationFeedbackMsg(
feedback_message, (FeedbackType.ERROR));
wipValidationResult result = new wipValidationResult(false, true);
result.addMessage(message);
return result;
}
/* Disable the action if there is no primary content. */
boolean objhasprimarycontent = hasPrimaryContent(workable);
logger.debug("objhasprimarycontent:" + objhasprimarycontent);
if (!objhasprimarycontent) {
return new wipValidationResult(false);
}
return performCheckoutValidation(validation_key, workable,
validation_criteria, validation_type, user);
}
}
return new wipValidationResult(false);
}
private WTReference getWTReference(Workable workable) {
if (refFactory == null) {
refFactory = new ReferenceFactory();
}
if (workable == null)
return null;
try {
return refFactory.getReference(workable);
} catch (WTException wte) {
return null;
}
}
/**
* ************* below are methods for backward compatible and should be
* removed later, 3/7/2007 ******************************
*/
/** @deprecated, for backward compatible only */
public UIValidationResult performCheckoutAndDownloadValidation(
UIValidationKey validation_key, Workable workable,
String validation_type) throws WTException {
WTUser user = (WTUser) SessionHelper.manager.getPrincipal();
return performCheckoutAndDownloadValidation(validation_key, workable,
null, validation_type, user).getValidationResult(
validation_key, getWTReference(workable), validation_type);
}
/** @deprecated, for backward compatible only */
public UIValidationResult performReplaceContentValidation(
UIValidationKey validation_key, Workable workable,
String validation_type) throws WTException {
WTUser user = (WTUser) SessionHelper.manager.getPrincipal();
return performReplaceContentValidation(validation_key, workable, null,
validation_type, user).getValidationResult(validation_key,
getWTReference(workable), validation_type);
}
public UIValidationResult performCheckinValidation(
UIValidationKey validation_key, Workable workable,
String validation_type, WTUser user) throws WTException {
return performCheckinValidation(validation_key, workable, null,
validation_type, user).getValidationResult(validation_key,
getWTReference(workable), validation_type);
}
public UIValidationResult performCheckoutValidation(
UIValidationKey validation_key, Workable workable,
String validation_type) throws WTException {
WTUser user = (WTUser) SessionHelper.manager.getPrincipal();
return performCheckoutValidation(validation_key, workable, null,
validation_type, user).getValidationResult(validation_key,
getWTReference(workable), validation_type);
}
public UIValidationResult performUndoCheckOutValidation(
UIValidationKey validation_key, Workable workable,
String validation_type) throws WTException {
WTUser user = (WTUser) SessionHelper.manager.getPrincipal();
return performUndoCheckoutValidation(validation_key, workable, null,
validation_type, user).getValidationResult(validation_key,
getWTReference(workable), validation_type);
}
/** @deprecated, for backward compatible only */
public UIValidationResult performEditValidation(
UIValidationKey validation_key, Workable workable,
String validation_type, UIValidationCriteria validation_criteria)
throws WTException {
WTUser user = (WTUser) validation_criteria.getUser().getPrincipal();
// (boolean result, UIValidationKey validation_key, WTReference wt_ref,
// String validation_type)
WTReference wt_ref = validation_criteria.getContextObject();
return performEditValidation(workable, user).getValidationResult(
validation_key, wt_ref, validation_type);
}
/** @deprecated, for backward compatible only */
public UIValidationResult performCheckoutAndEditValidation(
UIValidationKey validation_key, Workable workable,
String validation_type, UIValidationCriteria validation_criteria)
throws WTException {
WTUser user = (WTUser) validation_criteria.getUser().getPrincipal();
return performCheckoutAndEditValidation(validation_key, workable,
validation_criteria, validation_type, user)
.getValidationResult(validation_key, getWTReference(workable),
validation_type);
}
/*
* Helper methods used to call methods on other classes. These methods were
* pulled out so this class could be unit tested. THIS IS NOT THE PROPER WAY
* TO DO UNIT TESTS. This is a hack because Not all of the following classes
* implement interfaces.
*/
protected boolean hasAccess(WTPrincipal userP, Workable workable,
accessPermissions ap) throws WTException {
return AccessControlHelper.manager.hasAccess(userP, workable, ap
.getAccessPermission());
}
/**
* Determines if this object is checked out by anyone. (pulled out into it's
* own method for unit testing purposes) THIS IS NOT THE PROPER WAY TO DO
* UNIT TESTS. This is a hack because Not all of the following classes
* implement interfaces.
*
* @param workable
* @return
* @throws WTException
*/
protected boolean isCheckedOut(Workable workable) throws WTException {
// WorkInProgressHelper.
return WorkInProgressHelper.isCheckedOut(workable);
}
/**
* Determines if the current user was the one who checked out this document
* (pulled out into it's own method for unit testing purposes) THIS IS NOT
* THE PROPER WAY TO DO UNIT TESTS. This is a hack because Not all of the
* following classes implement interfaces.
*
* @param workable
* @param userP
* @return
* @throws WTException
*/
protected boolean isCheckedOutToUser(Workable workable, WTPrincipal userP)
throws WTException {
return WorkInProgressHelper.isCheckedOut(workable, userP);
}
/**
* Determines if the object is checked out to the sandbox (checked out to a
* project from a product or library) (pulled out into it's own method for
* unit testing purposes) THIS IS NOT THE PROPER WAY TO DO UNIT TESTS. This
* is a hack because Not all of the following classes implement interfaces.
*
* @param workable
* @return
* @throws WTException
*/
protected boolean isCheckedOutToSandbox(Workable workable)
throws WTException {
return SandboxHelper.isCheckedOutToSandbox(workable);
}
protected wt.inf.container.WTContainerService wTContainerService;
private wt.inf.container.WTContainerService getWTContainerService() {
if (wTContainerService == null) {
wTContainerService = WTContainerHelper.service;
}
return wTContainerService;
}
/**
* Determines if the object is the latest iteration of this version (pulled
* out into it's own method for unit testing purposes) THIS IS NOT THE
* PROPER WAY TO DO UNIT TESTS. This is a hack because Not all of the
* following classes implement interfaces.
*
* @param iterated
* @return
*/
protected boolean isLatestIteration(Iterated iterated) {
return VersionControlHelper.isLatestIteration(iterated);
}
protected boolean isCheckoutAllowed(Workable workable) throws WTException {
return WorkInProgressHelper.service.isCheckoutAllowed(workable);
}
protected wt.preference.PreferenceService2 preferenceService;
private wt.preference.PreferenceService2 getPreferenceService() {
if (preferenceService == null) {
preferenceService = PreferenceHelper.service;
}
return preferenceService;
}
/**
* Determines if the workable has file primary content (pulled out into it's
* own method for unit testing purposes) THIS IS NOT THE PROPER WAY TO DO
* UNIT TESTS. This is a hack because Not all of the following classes
* implement interfaces.
*
* @param workable
* @return
* @throws WTException
*/
protected boolean hasPrimaryContent(Workable workable) throws WTException {
if (workable instanceof FormatContentHolder) {
FormatContentHolder holder = null;
try {
holder = (FormatContentHolder) ContentHelper.service
.getContents((FormatContentHolder) workable);
} catch (PropertyVetoException pve) {
System.err.println(pve);
}
ContentItem item = ContentHelper.getPrimary(holder);
if (item == null || item instanceof URLData
|| item instanceof ExternalStoredData) {
return false;
}
return true;
}
return false;
}
} // end class