req.setAttribute(WebKeys.Field.FIELD, field);
}
private boolean _saveField(ActionForm form, ActionRequest req, ActionResponse res, User user) {
try {
FieldForm fieldForm = (FieldForm) form;
Field field = (Field) req.getAttribute(WebKeys.Field.FIELD);
Structure structure = StructureCache.getStructureByInode(field.getStructureInode());
boolean isNew = false;
boolean wasIndexed = field.isIndexed();
//http://jira.dotmarketing.net/browse/DOTCMS-5918
HttpServletRequest httpReq = ((ActionRequestImpl) req).getHttpServletRequest();
try {
_checkUserPermissions(structure, user, PERMISSION_PUBLISH);
} catch (Exception ae) {
if (ae.getMessage().equals(WebKeys.USER_PERMISSIONS_EXCEPTION)) {
SessionMessages.add(httpReq, "message", "message.insufficient.permissions.to.save");
}
throw ae;
}
String dataType = fieldForm.getDataType();
if (fieldForm.isListed()) {
fieldForm.setIndexed(true);
}
if (fieldForm.isSearchable()) {
fieldForm.setIndexed(true);
}
if (fieldForm.isUnique()) {
fieldForm.setRequired(true);
fieldForm.setIndexed(true);
}
BeanUtils.copyProperties(field, fieldForm);
//To validate values entered for decimal/number type check box field
//http://jira.dotmarketing.net/browse/DOTCMS-5516
if (field.getFieldType().equals(Field.FieldType.CHECKBOX.toString())){
String values = fieldForm.getValues();
String temp = values.replaceAll("\r\n","|");
String[] tempVals = StringUtil.split(temp.trim(), "|");
try {
if(dataType.equals(Field.DataType.FLOAT.toString())){
if(values.indexOf("\r\n") > -1) {
SessionMessages.add(req, "error", "message.structure.invaliddatatype");
return false;
}
for(int i=1;i<tempVals.length;i+= 2){
Float.parseFloat(tempVals[i]);
}
}else if(dataType.equals(Field.DataType.INTEGER.toString())){
if(values.indexOf("\r\n") > -1) {
SessionMessages.add(req, "error", "message.structure.invaliddatatype");
return false;
}
for(int i=1;i<tempVals.length;i+= 2){
Integer.parseInt(tempVals[i]);
}
}
}catch (Exception e) {
String message = "message.structure.invaliddata";
SessionMessages.add(req, "error", message);
return false;
}
}
// check if is a new field to add at the botton of the structure
// field list
if (!InodeUtils.isSet(fieldForm.getInode())) {
isNew = true;
int sortOrder = 0;
List<Field> fields = FieldsCache.getFieldsByStructureInode(structure.getInode());
for (Field f : fields) {
// http://jira.dotmarketing.net/browse/DOTCMS-3232
if (f.getFieldType().equalsIgnoreCase(fieldForm.getFieldType())
&& f.getFieldType().equalsIgnoreCase(Field.FieldType.HOST_OR_FOLDER.toString())) {
SessionMessages.add(req, "error", "message.structure.duplicate.host_or_folder.field");
return false;
}
if (f.getSortOrder() > sortOrder)
sortOrder = f.getSortOrder();
}
field.setSortOrder(sortOrder + 1);
field.setFixed(false);
field.setReadOnly(false);
String fieldVelocityName = VelocityUtil.convertToVelocityVariable(fieldForm.getFieldName(), false);
int found = 0;
if (VelocityUtil.isNotAllowedVelocityVariableName(fieldVelocityName)) {
found++;
}
String velvar;
for (Field f : fields) {
velvar = f.getVelocityVarName();
if (velvar != null) {
if (fieldVelocityName.equals(velvar)) {
found++;
} else if (velvar.contains(fieldVelocityName)) {
String number = velvar.substring(fieldVelocityName.length());
if (RegEX.contains(number, "^[0-9]+$")) {
found++;
}
}
}
}
if (found > 0) {
fieldVelocityName = fieldVelocityName + Integer.toString(found);
}
//http://jira.dotmarketing.net/browse/DOTCMS-5616
if(!validateInternalFieldVelocityVarName(fieldVelocityName)){
fieldVelocityName+="1";
}
field.setVelocityVarName(fieldVelocityName);
}
if (!field.isFixed() && !field.isReadOnly()) {
// gets the data type from the contentlet: bool, date, text, etc
String prevDataType = (field.getFieldContentlet() != null) ? field.getFieldContentlet().replaceAll(
"[0-9]*", "") : "";
if (field.getFieldType().equals("categories_tab") || field.getFieldType().equals("permissions_tab")
|| field.getFieldType().equals("relationships_tab")) {
List<Field> structureFields = FieldsCache.getFieldsByStructureInode(structure.getInode());
for (Field f : structureFields) {
if (f.getFieldType().equals("categories_tab") && field.getFieldType().equals("categories_tab")
&& !f.getInode().equals(field.getInode())) {
String message = "message.structure.duplicate.categories_tab";
SessionMessages.add(req, "error", message);
return false;
} else if (f.getFieldType().equals("permissions_tab")
&& field.getFieldType().equals("permissions_tab")
&& !f.getInode().equals(field.getInode())) {
String message = "message.structure.duplicate.permissions_tab";
SessionMessages.add(req, "error", message);
return false;
} else if (f.getFieldType().equals("relationships_tab")
&& field.getFieldType().equals("relationships_tab")
&& !f.getInode().equals(field.getInode())) {
String message = "message.structure.duplicate.relationships_tab";
SessionMessages.add(req, "error", message);
return false;
}
}
}
if (!(field.getFieldType().equals("host or folder") || field.getFieldType().equals("line_divider") || field.getFieldType().equals("tab_divider")
|| field.getFieldType().equals("categories_tab")
|| field.getFieldType().equals("permissions_tab") || field.getFieldType().equals(
"relationships_tab"))
&& !UtilMethods.isSet(fieldForm.getDataType())) {
// it's either an image, file or link so there is no
// datatype
field.setFieldContentlet("");
}
if (!UtilMethods.isSet(fieldForm.getDataType())) {
// it's either an image, file or link so there is no
// datatype
if (!field.getFieldType().equals("host or folder")){
field.setFieldContentlet("");
}
} else if (!prevDataType.equals(fieldForm.getDataType())) {
String fieldContentlet = FieldFactory.getNextAvaliableFieldNumber(dataType, field.getInode(), field
.getStructureInode());
if (fieldContentlet == null) {
// didn't find any empty ones, so im throwing an error
// to the user to select a new one
String message = "message.structure.nodatatype";
SessionMessages.add(req, "error", message);
return false;
}
field.setFieldContentlet(fieldContentlet);
}
if (field.getFieldType().equalsIgnoreCase(Field.FieldType.CATEGORY.toString())) {
field.setValues(req.getParameter("categories"));
field.setIndexed(true);
// validate if a field with the same category already exists
List<Field> stFields = FieldsCache.getFieldsByStructureInode(field.getStructureInode());
for (Field stField : stFields) {
if(stField.getFieldType().equalsIgnoreCase(Field.FieldType.CATEGORY.toString())
&& UtilMethods.isSet(stField.getValues())
&& stField.getValues().equals(field.getValues())
&& !stField.getInode().equals(field.getInode())) {
SessionMessages.add(httpReq, "message", "message.category.existing.field");
return false;
}
}
if (UtilMethods.isSet(fieldForm.getDefaultValue())) {
List<Category> selectedCategoriesList = new ArrayList<Category>();
String[] selectedCategories = fieldForm.getDefaultValue().trim().split("\\|");
for (String cat : selectedCategories) {
selectedCategoriesList.add(categoryAPI.findByName(cat, user, false));
}
Category category = categoryAPI.find(req.getParameter("categories"), user, false);
List<Category> childrenCategories = categoryAPI.getChildren(category, user, false);
if (!childrenCategories.containsAll(selectedCategoriesList)) {
String message = "error.invalid.child.category";
SessionMessages.add(req, "error", message);
return false;
}
}
}
if (field.getFieldType().equalsIgnoreCase(Field.FieldType.TAG.toString()) || field.isSearchable()) {
field.setIndexed(true);
}
}
if (fieldForm.getElement().equals(FieldAPI.ELEMENT_CONSTANT) || fieldForm.getFieldType().equals(FieldAPI.ELEMENT_CONSTANT)) {
field.setFieldContentlet(FieldAPI.ELEMENT_CONSTANT);
field.setValues(fieldForm.getValues());
}
boolean isUpdating = UtilMethods.isSet(field.getInode());
// saves this field
FieldFactory.saveField(field);
if(isUpdating) {
ActivityLogger.logInfo(ActivityLogger.class, "Update Field Action", "User " + _getUser(req).getUserId() + "/" + _getUser(req).getFirstName() + " modified field " + field.getFieldName() + " to " + structure.getName()
+ " Structure.", HostUtil.hostNameUtil(req, _getUser(req)));
} else {
ActivityLogger.logInfo(ActivityLogger.class, "Save Field Action", "User " + _getUser(req).getUserId() + "/" + _getUser(req).getFirstName() + " added field " + field.getFieldName() + " to " + structure.getName()
+ " Structure.", HostUtil.hostNameUtil(req, _getUser(req)));
}
FieldsCache.removeFields(structure);
StructureCache.removeStructure(structure);
StructureServices.removeStructureFile(structure);
StructureFactory.saveStructure(structure);
FieldsCache.addFields(structure, structure.getFields());
//Refreshing permissions
PermissionAPI perAPI = APILocator.getPermissionAPI();
if(field.getFieldType().equals("host or folder")) {
perAPI.resetChildrenPermissionReferences(structure);
}
//http://jira.dotmarketing.net/browse/DOTCMS-5178
if(!isNew && ((!wasIndexed && fieldForm.isIndexed()) || (wasIndexed && !fieldForm.isIndexed()))){
// rebuild contentlets indexes
conAPI.reindex(structure);
}
if (fAPI.isElementConstant(field)) {